모두의 코드 커뮤니티

그래서 자세히 밝혀 적어봅니다

저는 함수 호출 과정을 쉽게 초보자 수준에서 알려달라고 했었고요 이전 답변에서 예제 코드의 a는 어떻게 살아 있게 되는지 궁금합니다.

저는 함수 호출 과정을 쉽게 초보자 수준에서 알려달라고 했었고요

모든 지역 변수들은 스택이라는 메모리 구조에 저장됩니다. 스택(stack) 이 뭐냐면 먼저 들어간 놈이 나중에 나온다 라는 방식의 자료 구조인데, 쉽게 생각해서 책들을 쌓는 것이라 보면 됩니다. 책들을 책상 위에 쭈르륵 쌓아놓는 것을 생각해보면, (중간에 책을 뺄 수 없다고 가정할 때) 맨 마지막에 올려놓은 책을 맨 먼저 뺄 수 있지요? 반대로 말하자면 맨 처음 깔은 책을 빼려면 그 위에 모든 책들을 빼야 합니다.

이 메모리의 스택도 마찬가지로 생각하면 됩니다. 메모리에도 지역 변수를 정의할 때 마다 책 한 권을 쌓는 다고 생각하면 됩니다.

예를 들어서 지역 변수 a 를 정의하면

+------------+
|            |
|   a        |  0x1234  <-- ESP
|            |
+------------+

위와 같이 0x1234 라는 위치에 지역 변수 a 의 값이 저장이 되어 있습니다. 그리고 CPU 에는 이 스택의 맨 끝을 나타내는 레지스터가 있는데 이를 ESP 레지스터 라고 합니다. 참고로 책의 경우 아래에서 위로 쌓지만 메모리의 스택은 거꾸로 위에서 아래로 (높은 주소값에서 낮은 주소값으로) 내려갑니다.

만약에 새로운 지역 변수를 생성하게 되면, ESP 의 값이 줄어들면서 (스택에 push) 바로 아래 칸에 새로운 지역 변수가 생성됩니다. 예를 들어서 지역 변수 b 를 생성했다고 쳐봅시다. 이는 마치 a 라는 책 위에 b 라는 책을 쌓은 셈이라 보시면 됩니다.

+------------+
|            |
|   a        |  0x1234
|            |
+------------+
|            |
|   b        |  0x1230  <-- ESP 
|            |
+------------+

a 의 크기가 4 바이트라 생각하면 b 는 1234 에서 4 바이트 아래인 1230 에 위치하게 되겠지요. 그리고 ESP 는 4 만큼 줄게 됩니다. 이제 해당 상태에서는 a 와 b 가 모두 메모리에 살아있는 상태 입니다.

근데 C 에서 해당 스코프를 빠져나가게 된다면 해당 스코프에서 생성된 모든 변수는 파괴된다고 하였습니다. 이 말이 무슨 말이냐면 그냥 ESP 를 줄어든 만큼 다시 늘린다는 것입니다.

예를 들어서 b 가 소멸 된다는 말은 그냥 ESP 에 4 를 더해서

+------------+
|            |
|   a        |  0x1234 <-- ESP 
|            |
+------------+
|            |
|   b        |  0x1230  
|            |
+------------+

와 같은 상태가 되다는 뜻입니다. 물론 b 의 값은 메모리에서 지워지는 것은 아니지만 언제든지 다른 변수에 의해서 덮어 씌어질 수 있습니다. 예를 들어서 새로운 지역 변수 c 를 생성한다면

+------------+
|            |
|   a        |  0x1234
|            |
+------------+
|            |
|   c        |  0x1230  <-- ESP 
|            |
+------------+

가 되겠죠?

이전 답변에서 예제 코드의 a는 어떻게 살아 있게 되는지 궁금합니다.

함수를 호출한다는 뜻은 단순히 메모리에 리턴할 주소를 push 해놓고 해당 함수로 점프한다는 의미 입니다. 리턴 주소가 뭐냐면, 함수의 실행이 끝나면 원래 실행한 자리로 다시 되돌아가야 하는데, 어디로 되돌아가야 할지 적어놓은 주소라고 보시면 됩니다.

예를 들어서 func2 를 호출한다면

호출하기 전에 메모리 의 상태

+------------+
|            |
|   a        |  0x1234  <-- ESP
|            |
+------------+

func2 안에 들어왔을 때 메모리 상태

+------------+
|            |
|   a        |  0x1234
|            |
+------------+
|            |
|   리턴주소   |  0x1230
|            |
+------------+
|            |
|   b        |  0x122C  <- ESP
|            |
+------------+

와 같은 상태가 됩니다. func2 의 실행이 종료되면 다시 ESP 가 pop 되면서

+------------+
|            |
|   a        |  0x1234 <- ESP
|            |
+------------+
|            |
|   리턴주소   |  0x1230
|            |
+------------+
|            |
|   b        |  0x122C  
|            |
+------------+

처럼 되겠죠? 그래서 이전에 있었던 a 도 접근할 수 있는 거구요.

저도 이렇게 이해하면 이해가 됩니다. 하지만 이렇게 하면 실전 프로그램에서 함수 호출과정을 이해하기 너무 어려워 질문한 것입니다.

저도 이렇게 이해하면 이해가 됩니다.

정말 이해 하신거 맞나요?

하지만 이렇게 하면 실전 프로그램에서 함수 호출과정을 이해하기 너무 어려워 질문한 것입니다.

실전 프로그램에서도 함수 호출과정이 별반 다를게 없을것 같은데요?
실전 프로그램을 한 번 들고와주시죠 그럼

아무 프로그램으로나 호출에도 읽어볼 때 함수 호출 과정을 이해하면 너무 힘듭니다…

#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
#include <Windows.h>
#define SPACE 32//스페이스를 나타내는 매크로
#define UP 72//키보드 방향키 윗키를 나타내는 매크로
#define DOWN 80//키보드 방향키 아랫키를 나타내는 매크로
struct time//일정 구조체
{
int date;//날짜
int hour;//시간
int importance;//중요도
int groop;//그룹
int arrow;//화살표의 유무
char title[127];//제목
char contents[127];//내용
};//일정 구조체
int x[5] = { 0,0,0,0,0 };//배열의 현재 항목 개수(항목의 끝)을 나타냄
int y[5] = { 8,8,8,8,8 };//동적 할당된 항목 개수 를 나타냄, 동적 할당된 최대치보다 커지면 재할당됨
void input(struct time* a[5])//입력하기
{
int date;
int hour;
int importance;
int groop;
char title[127];
char contents[127];//time 구조체에 넣기 위한 변수들
FILE* file;//파일 구조체
file = fopen(“data.txt”, “r”);//파일 읽어들이기(r모드로 열었기 때문에 파일이 없으면 새로 만들어야 함)(아니면 오류남).
if (file == NULL)//파일이 없으면
{
printf(“파일이 존재하지 않습니다.”);//존재하지 않는다고 출력
exit(0);//강제 종료
}
for (int i = 0; i < 5; i++)
{
a[i] = (struct time*)malloc(sizeof(struct time) * 8);//기본 8개로 동적 할당
}
while (EOF != fscanf(file, “%d %d %d %d %s %s”, &date, &hour, &importance, &groop, title, contents))//파일의 끝까지 얻어오기
{
a[groop][x[groop]].date = date;
a[groop][x[groop]].hour = hour;
a[groop][x[groop]].importance = importance;
a[groop][x[groop]].groop = groop;
strcpy(a[groop][x[groop]].title, title);
strcpy(a[groop][x[groop]].contents, contents);//배열에 대입

	x[groop]++;//현재 배열 항목의 개수 1 늘리기
	if (x[groop] == y[groop])//만약 현재 배열 항목의 개수가 동적 할당된 항목 개수와 같다면
	{
		y[groop] = y[groop] * 2;//동적 할당할 배열의 항목 개수를 두배로 늘리기


		a[groop] = (struct time*)realloc(a[groop], (sizeof(struct time)) * y[groop]);//그리고 재할당


	}

}
fclose(file);//파일 닫기

}
int output(struct time* b[5])//출력 함수
{//
system(“cls”);//원래 있던 것을 지우기

printf("   날짜       시간   중요도    그룹   제목     내용\n");
for (int i = 0; i < 5; i++)
{
	for (int j = 0; j < x[i]; j++)//끝까지 반복
	{
		if (b[i][j].arrow == 1)//항목에 화살표가 있다면
		{
			printf("▶ ");//화살표 출력
		}
		else//아니면
		{
			printf("   ");//그냥 공백 출력
		}
		int date01 = b[i][j].date / 10000, date02 = b[i][j].date % 10000 / 100, date03 = b[i][j].date % 10000 % 100;//.으로 나눌 수 있게 년,월,일로 나눔
		int time01 = b[i][j].hour / 100, time02 = b[i][j].hour % 100;//시간도 시,분으로 나눔
		if (date01 < 10)//년 10보다 작으면
		{
			printf("0%d.", date01);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d.", date01);//그냥 출력
		}
		if (date02 < 10)//월이 10보다 작으면
		{
			printf("0%d.", date02);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d.", date02);//그냥 출력
		}
		if (date03 < 10)//일이 10보다 작으면
		{
			printf("0%d ", date03);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d ", date03);//그냥 출력
		}
		if (time01 < 10)//'시'가 0보다 작으면
		{
			printf("0%d:", time01);//앞예 0 붙여 출력
		}
		else//아니면 
		{
			printf("%d:", time01);//그냥 출력
		}
		if (time02 < 10)//분이 0보다 작으면
		{
			printf("0%d ", time02);//앞에 0 붙여 출력

		}
		else
		{
			printf("%d ", time02);//아니면 그냥 출력

		}
		printf("%d           ", b[i][j].importance);//중요도 출력
		if (b[i][j].groop == 0)
			printf("공부 ");
		if (b[i][j].groop == 1)
			printf("상담 ");
		if (b[i][j].groop == 2)
			printf("약속 ");
		if (b[i][j].groop == 3)
			printf("휴식 ");
		if (b[i][j].groop == 4)//그룹에 맞게 출력
			printf("운동 ");
		
	
		printf("%s %s\n", b[i][j].title, b[i][j].contents);//그리고 나머지 출력

	}
}

}
int write(struct time* b[5])//파일에 넣는 함수
{
FILE* file = fopen(“data.txt”, “w”);//파일 읽기
if (file == NULL)//파일이 없으면
{
printf(“파일이 존재하지 않습니다.”);//존재하지 않는다고 출력
exit(0);//강제 종료
}
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < x[i]; j++)
{

		fprintf(file, "%d %d %d %d %s %s\n", b[i][j].date, b[i][j].hour, b[i][j].importance, b[i][j].groop, b[i][j].title, b[i][j].contents);//항목 쓰기
	}
}
fclose(file);//파일 닫기

}
int main(int argc, char* argv[])
{
int key = 0;//키 변수
struct time* b[5];//배열 만들기.
int k, p;//맨 처음 항목을 가르키는 변수
input(b);//입력하고
for (k = 0; k < 5; k++)//배열의 첫 항목 찾기
{
if (x[k] != 0)
break;
}
b[k][0].arrow = 1;//배열의 첫 항목에 화살표 넣기
output(b);//출력하기
while (1) {
for (k = 0; k < 5; k++)//배열의 첫 항목 찾기
{
if (x[k] != 0)
break;
}
/* implement here */
int i, j;//현재 화살표의 위치를 구하는 변수

	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < x[i]; j++)
		{
			if (b[i][j].arrow == 1)
			{
				goto outside;
			}
		}
	}//구하기
outside:
	key = getch();//키 입력받기
	if (key == 224) key = getch();//방향키 입력받기
	if (key == UP)//방향키가 위일때
	{

		if (i == k && j == 0)//항목의 맨 처음에서 올리려 할 때는
		{//아무것도 하지 않기
		}
		else if (j == 0)//두 그룹이 다를 때
		{
			int od = 0;
			for (od = i - 1; od > 0; --od)
			{

				if (x[od] != 0)
				{
					break;
				}

			}//현재 그룹의 이전 그룹에서 비어있지 않은 그룹 찾기
			b[od][x[od] - 1].arrow = 1;//거기로 화살표 옮기고
			b[i][j].arrow = 0;//원래 화살표 없에기


		}

		else {//아니명
			b[i][j].arrow = 0;//원래 화살표 없에고
			b[i][j - 1].arrow = 1;//한 칸 위의 화살표 나타내기

		}
		output(b);//출력시키기
	}
	else if (key == DOWN) {//아랫 키일 떄
		int p = 4;//바로 아랫 키가 마지막인지 구하기

		for (; p > 0; p--)
		{
		
			if (x[p] != 0)
			{
				break;
			}

		}//현재 그룹이 맨 끝 그룹인지 구하기
	
		if (i == p && j + 1 == x[i])//만약 다음 화살표가 전체의 맨 끝 화살표라면
		{

		}//아무것도 안하기
		else if (j + 1 == x[i])//현재 그룹의 끝이고 다음 그룹이 있다면
		{
			int od = 0;
			for (od = i + 1; od < 5; od++)
			{
				if (x[od] != 0)
					break;
			}//다음 그룹 구하고
			b[i][j].arrow = 0;
			b[od][0].arrow = 1;//화살표 바꾸기


		}
		else//아니면
		{
			b[i][j].arrow = 0;
			b[i][j + 1].arrow = 1;//현재 화살표의 다음 화살표로 바꾸기

		}
		output(b);//바뀐 값 출력시키기
	}
	else if (key == 32)//space키를 눌렀다면
	{
		system("cls");//화면 초기화
		int date01 = b[i][j].date / 10000, date02 = b[i][j].date % 10000 / 100, date03 = b[i][j].date % 10000 % 100;//.으로 나눌 수 있게 년,월,일로 나눔
		int time01 = b[i][j].hour / 100, time02 = b[i][j].hour % 100;//시간도 시,분으로 나눔
		printf("일시: ");
		if (date01 < 10)//죄송합니다. 선생님이 질문을 해도 답을 안 하시는 것 같아서 반복적인 if-else 문으로 ㅎ하였습니다.//년 10보다 작으면
		{
			printf("0%d.", date01);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d.", date01);//그냥 출력
		}
		if (date02 < 10)//월이 10보다 작으면
		{
			printf("0%d.", date02);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d.", date02);//그냥 출력
		}
		if (date03 < 10)//일이 10보다 작으면
		{
			printf("0%d ", date03);//앞에 0 붙여 출력
		}
		else//아니면
		{
			printf("%d ", date03);//그냥 출력
		}
		if (time01 < 10)//'시'가 0보다 작으면
		{
			printf("0%d:", time01);//앞예 0 붙여 출력
		}
		else//아니면 
		{
			printf("%d:", time01);//그냥 출력
		}
		if (time02 < 10)//분이 0보다 작으면
		{
			printf("0%d\n", time02);//앞에 0 붙여 출력

		}
		else
		{
			printf("%d\n", time02);//아니면 그냥 출력

		}
		printf("중요도: %d\n", b[i][j].importance);//중요도 출력
		if (b[i][j].groop == 0)
		{
			printf("그룹: 공부\n");
		}
		else if (b[i][j].groop == 1)
		{
			printf("그룹: 상담\n");
		}
		else if (b[i][j].groop == 2)
		{
			printf("그룹: 약속\n");
		}
		else if (b[i][j].groop == 3)
		{
			printf("그룹: 휴식\n");
		}
		else if (b[i][j].groop == 4)
		{
			printf("그룹: 운동");
		}//구분하여 그룹 출력
		printf("제목: %s\n", b[i][j].title);//제목과 내용 출력
		printf("내용: %s\n", b[i][j].contents);
		printf("q 키나 방향키를 눌러 이 화면을 나갈 수 있음\n");//나가는 법 고지
	}
	if (key == 'q' || key == 'Q')//나갈려고 할 떄
	{
		output(b);//다시 출력시키기
	}
	if (key == 'i' || key == 'I')//i 키를 눌렀을때
	{
		int date;
		int hour;
		int importance;
		int groop;
		char groopp[127];
		char title[127];
		char contents[127];
		printf("날짜를 입력해 주세요: ");
		scanf("%d", &date);
		printf("시간을 입력하세요: ", &hour);
		scanf("%d", &hour);
		printf("중요도를 입력하세요: ");
		scanf("%d", &importance);
		printf("그룹을 입력하세요: ");
		scanf("%s", &groopp);
		if (!strcmp(groopp, "공부"))
		{
			groop = 0;
		}
		else	if (!strcmp(groopp, "상담"))
		{
			groop = 1;
		}
		else if (!strcmp(groopp, "약속"))
		{
			groop = 2;
		}
		else if (!strcmp(groopp, "휴식"))
		{
			groop = 3;
		}
		else if (!strcmp(groopp, "운동"))//그룹에 맞게 출력
		{
			groop = 4;
		}
		else//잘못 입력했다면
		{
			groop = 0;//그룹을 '공부'로 정하기
		}
		printf("제목을 입력하세요: ");
		scanf("%s", &title);
		printf("내용을 입력하세요: ");
		scanf("%s", &contents);//제목과 내용 입력
		b[groop][x[groop]].date = date;

		b[groop][x[groop]].hour = hour;
		b[groop][x[groop]].importance = importance;
		b[groop][x[groop]].groop = groop;

		strcpy(b[groop][x[groop]].title, title);
		strcpy(b[groop][x[groop]].contents, contents);//대입
		x[groop] += 1;//그룹의 항목 개수에 1 추가
		if (x[groop] >= y[groop])//만약 현재 배열 항목의 개수가 동적 할당된 항목 개수와 같다면
		{
			y[groop] = y[groop] * 2;


			b[groop] = (struct time*)realloc(b[groop], (sizeof(struct time)) * y[groop]);//그리고 재할당


		}//재할당 시키기



		output(b);//변경 내용 출력

		write(b);//파일에 쓰기
	}
	if (key == 'e' || key == 'E')//e(수정) 키를 눌렀을 때
	{
		int date;
		int hour;
		int importance;
		int groop;
		char groopp[127];
		char title[127];
		char contents[127];
		char groop2[127];
		if (b[i][j].groop == 0)
		{
			strcpy(groop2, "공부");
		}
		if (b[i][j].groop == 1)
		{
			strcpy(groop2, "상담");

		}
		if (b[i][j].groop == 2)
		{
			strcpy(groop2, "약속");
		}
		if (b[i][j].groop == 3)
		{
			strcpy(groop2, "휴식");
		}
		if (b[i][j].groop == 4)
		{
			strcpy(groop2, "운동");
		}//현재 그룹 알아내기
		printf("수정할 내용을 입력해 주세요, 수정하지 않으실 거라면 0을 입력해주세요\n");//안내 문자 추가
		printf("날짜를 입력해 주세요(%d): ", b[i][j].date);
		scanf("%d", &date);
		if (date == 0)//만약 0이라면
		{

			date = b[i][j].date;
			printf("%d", b[i][j].date);
		}//같게 하기

printf(“시간을 입력하세요(%d): “, b[i][j].hour);
scanf(”%d”, &hour);
if (hour == 0)
{
hour = b[i][j].hour;
}
printf(“중요도를 입력하세요(%d): “, b[i][j].importance);//갑에 원래 그룹을 표시하여 출력
scanf(”%d”, &importance);
if (importance == 0)//만약 0이라면
{
importance = b[i][j].importance;
} //같게 하기
printf(“그룹을 입력하세요(%s): “, groop2);//
scanf(”%s”, &groopp);
if (!strcmp(groopp, “공부”))
{
groop = 0;
}
else if (!strcmp(groopp, “상담”))
{
groop = 1;
}
else if (!strcmp(groopp, “약속”))
{
groop = 2;
}
else if (!strcmp(groopp, “휴식”))
{
groop = 3;
}
else if (!strcmp(groopp, “운동”))
{
groop = 4;
}
else//다른 값이나 0이 입력되었다면
{
groop = b[i][j].groop;//같게 하기
}//그룹 알아내기

		printf("제목을 입력하세요(%s): ", b[i][j].title);
		scanf("%s", &title);
		if (!strcmp(title, "0"))//만약 0이라면
		{
			strcpy(title, b[i][j].title);
		}//같게 하기
		printf("내용을 입력하세요(%s): ", b[i][j].contents);
		scanf("%s", &contents);//제목과 내용 입력
		if (!strcmp(contents, "0"))//만약 0이라면
		{
			strcpy(contents, b[i][j].contents);
		}//같게 하기
		if (i != groop)//현재 그룹과 바뀔 그룹이 다르다면
		{
			b[i][j].arrow = 0;//화살표 없애기
			for (int kp = j; kp < x[i] - 1; kp++)
			{
				b[i][kp].date = b[i][kp + 1].date;
				b[i][kp].hour = b[i][kp + 1].hour;
				b[i][kp].importance = b[i][kp + 1].importance;
				b[i][kp].groop = b[i][kp + 1].groop;
				strcpy(b[i][kp].title, b[i][kp + 1].title);
				strcpy(b[i][kp].contents, b[i][kp + 1].contents);
			}//현재 그룹에서 항목 빼기
			x[i]--;//현재 그룹의 항목 수 1 줄이기
			x[groop]++;//현재 그룹의 항목 수 1 늘리기
			i = groop;//그룹과
			j = x[groop] - 1;//좌표 바꾸기

		}
		b[i][j].date = date;

		b[i][j].hour = hour;
		b[i][j].importance = importance;
		b[i][j].groop = groop;
		b[i][j].arrow = 1;
		strcpy(b[i][j].title, title);
		strcpy(b[i][j].contents, contents);
		output(b);
		write(b);//대입하기
	}
	else if (key == 'd' || key == 'D')//d(삭제) 키를 눌렀을 때
	{
		printf("진짜로 삭제하시겠습니까?(y(예),n(아니요)으로 표시하세요)\n");//진짜 삭제 할 것인지 물어보기
		char key2 = getch();//입력시키기
		if (key2 == 'y' || key2 == 'Y')//그렇다면
		{

		}//그냥 넘어가기
		else//잘못 눌렀다면
		{
			output(b);//다시 출력하고
			continue;//맨 처음으로
		}
		x[i]--;//현재 배열의 항목 수를 1을 줄여보고
		if (x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0 && x[4] == 0)//이거 하나밖에 벗으면
		{
			x[i]++;//다시 늘리고
			printf("삭제 할 수 없습니다.");//삭제 할 수 없다고 출력(하나밖에 없다면 다른 기능도 작동되지 않음)


			Sleep(1000);//잠시 기다려서 인지 할 수 있게 하였다가
			output(b);//다시 출력
			continue;//처음으로...
		}

		x[i]++;//다시 늘리기
		b[i][j].arrow = 0;//화살표 없에고
		int kq;
		if (x[i] <= 2)//현재i의 값이 2 이하라면
		{
			kq = x[i];//그냥 있기
		}
		else//아니면
		{
			kq = x[i] - 1;//1 줄이기
		}

		for (int kp = j; kp < kq; kp++)
		{

			b[i][kp].date = b[i][kp + 1].date;
			b[i][kp].hour = b[i][kp + 1].hour;
			b[i][kp].importance = b[i][kp + 1].importance;
			b[i][kp].groop = b[i][kp + 1].groop;
			strcpy(b[i][kp].title, b[i][kp + 1].title);
			strcpy(b[i][kp].contents, b[i][kp + 1].contents);
		}//삭제하기


		x[i]--;//항목 1 줄이기
		for (k = 0; k < 5; k++)
		{
			if (x[k] != 0)
				break;
		}//현재 맨 위의 항목 찾기

		b[k][0].arrow = 1;//맨 위로 화살표 이동
		output(b);//출력
		write(b);//파일에 쓰기
	}

}

for (int i = 0; i < 5; i++)
{
	free(b[i]);//동적 할당 해제
}

}

좋습니다

그러면 어떤 함수의 호출과정이 이해가 안되는지 얘기해주세요.

예를 들어 여기서 output 함수를 호출할 때마다는 호출할 때마다 변수의 메모리 구조를 표시해서 이해하기는 변수나 코드들이 너무 많아 그 방법으로는 이해하기 어렵습니다.
다른 함수들도요

예를 들어 여기서 output 함수를 호출할 때마다는 호출할 때마다 변수의 메모리 구조를 표시해서 이해하기는 변수나 코드들이 너무 많아 그 방법으로는 이해하기 어렵습니다.

저는 도무지 작성자님이 왜 변수의 메모리 구조를 표시해서 이해하고 싶어하는지 알 수 가 없네요ㅎㅎ 그걸 알아서 뭐에 쓰게요? 리버싱이라도 하시는 건가요?

머 여하튼 궁금하다는데 어쩔 수 없죠.

예를 들어봅시다.

int output(struct time * b[5]) //출력 함수
{ //
  system(“cls”); //원래 있던 것을 지우기
  printf("   날짜       시간   중요도    그룹   제목     내용\n");
  for (int i = 0; i < 5; i++) {
    for (int j = 0; j < x[i]; j++) //끝까지 반복
    {
      if (b[i][j].arrow == 1) //항목에 화살표가 있다면
      {
        printf("▶ "); //화살표 출력
        // 여기에서의 메모리 상태는???      

제가 거꾸로 한 번 물어볼께요.

위 주석 처리된 여기에서의 메모리 상태는 어떤 상태일까요? 정확한 값 말고 스택에 어떤 변수들이 들어가있는지 얘기해보세요. (현재 함수의 스택만 고려해봅시다) 아마 제 답변을 제대로 읽었더라면 답하실 수 있을 것입니다.

b,i,j가 스택에 들어가 있습니다.
그러면 함수 호출을 더 쉽게 이해할수 있는 방법이 있나요?
그것을 물어본 것이잖아요…

그리고 님이 메모리 구조로 알아보라고 첫 답변이 썻잖아요

그 힘수 호출 시 스택 구조가 메모리 구조 아닌가요?

b,i,j가 스택에 들어가 있습니다.
그러면 함수 호출을 더 쉽게 이해할수 있는 방법이 있나요?
그것을 물어본 것이잖아요…

질문을 그런식으로 하면 정확히 뭘 모르겠는지 알 수 가 없어요

그냥 뭉뚱그려서 “함수의 호출과정이 이해가 안되요” 라고 물어보면 함수의 호출이 컴퓨터 내부적으로 어떻게 이루어지는지를 모르겠다는 건지 아니면 그냥 어떤 함수 output 이 어느 경로에서 호출되었는지 모르겠다 이소린지 제가 어떻게 아나요.

다음부터는 질문을 정확하게 하시는 법을 배우시기 바랍니다.

그냥 어떤 경로에서 output 이 호출된건지 궁금한건가요?

어떤 경로라는 말은 무엇인가요?

내부적인 컴퓨터 과정이 아닌 대략적인 과정이 궁급합니다. 그래서 초보자 수준이라고 했고요.
너무 무리한 질문을 했드면 죄송합니다

이해하기 어려우시다면 image004
이 그림처럼 설명해 주시면 좋겠지만 호출한 함수의 변수가 어떻게 되는지도 설명해 주시면 감사하겠습니다.