1 / 33

CHAPTER 09. 변수의 참조 영역과 지속 기간

CHAPTER 09. 변수의 참조 영역과 지속 기간. 변수의 참조 영역과 지속 기간을 이해한다 . 지역 변수와 전역 변수의 차이를 이해한다 . 자동 변수와 정적 변수의 차이를 이해한다 . 정적 지역 변수와 정적 전역 변수의 차이를 이해한다 . 전역 변수 사용 시 장점과 단점을 이해한다 . 정적 변수의 필요성을 이해한다. 9.0 개요 p.400. 변수 참조 (access) 변수에 해당하는 기억장소를 참조하여 저장된 값을 읽어오거나 새로운 값을 저장하는 것 변수의 구분 참조 영역에 따른 구분

Download Presentation

CHAPTER 09. 변수의 참조 영역과 지속 기간

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CHAPTER 09. 변수의 참조 영역과 지속 기간 변수의 참조 영역과 지속 기간을 이해한다. 지역 변수와 전역 변수의 차이를 이해한다. 자동 변수와 정적 변수의 차이를 이해한다. 정적 지역 변수와 정적 전역 변수의 차이를 이해한다. 전역 변수 사용 시 장점과 단점을 이해한다. 정적 변수의 필요성을 이해한다.

  2. 9.0 개요 p.400 • 변수 참조(access) 변수에 해당하는 기억장소를 참조하여 저장된 값을 읽어오거나 새로운 값을 저장하는것 • 변수의 구분 • 참조 영역에 따른 구분 • 지속 기간에 따른 구분  이 두 가지 혼용하여 여러 가지로 구분할 수 있다. ch= ‘A’; // 쓰기 printf(“%c”, ch); // 읽기 참조

  3. 9.0 개요 p.400 • 참조 영역(에따른 분류) • 참조 영역 • 변수가 유효한(valid) 영역 즉 변수를 참조할 수 있는 영역 • 변수의 참조 영역을 벗어난 곳에서 참조를 시도하면? 에러 • 지역 변수 • 전역 변수

  4. 9.0 개요 p.400 • 지속(영속) 기간(duration) 또는 수명(lifetime) • 변수가 존재하는 기간즉 변수에 기억장소가 할당되어 있는 기간  이 기간 안에서만 변수를 참조할 수있다. • 자동, 정적, 외부, 레지스터 변수로 구분

  5. 9.1 지역(local) 변수 p.401 • 지역(local) 변수 • 블록 ({ .. }) 안에서 선언 • 자신이 선언된 블록({ .. }) 안에서만 참조 • 지속 기간은 자신이 선언된 블록의 실행 기간 → 블록 실행이 끝나면 주기억장치에서 제거되므로 참조 불가능

  6. 9.1.1 함수 본체에서 선언한 지역 변수 p.401 • 함수에서 선언한 지역 변수 • 지역 변수의 선언 반환형 함수명(매개변수선언목록) { 자료형 지역 변수1; 자료형 지역 변수2; : 함수 본체의 나머지 코드 } 함수의 지역 변수 함수밖에서는 참조 불가능

  7. 9.1.2 블록에서 선언한 지역 변수 p.404 • 블록 {}에서 선언한 지역 변수 • 임의의 { } 안에서 변수 선언 가능 → 블록 안에서만 참조 가능 • ㈜ C언어는 블록 안의 선언문이 반드시 다른 실행문 이전에 위치해야 함  [프로그램 9-3]의 14행 이후 int height;로 선언하면 에러

  8. 9-3 블록에서 선언한 지역 변수 참조 영역 예 p.404 4 int main() 5 { 6 int i, sum; 7 8 sum = 0; 9 for (i=0; i<N; i++) 10 { 11 int height; // for 블록의 지역 변수 선언 12 13 printf("%d번의 키는? ", i+1); 14 scanf("%d", &height); 15 sum += height; 16 } // for 블록의 끝 17 18 printf("평균 키: %.1lf cm \n", (double)sum/N); 19 20 return 0; 21 } // main 블록의 끝 main 함수의지역 변수 → 5~21행에서만 참조 가능 for 블록의 지역 변수 → 10~16행에서만 참조 가능 height 참조 불가 • Q) 다음을 추가하면? • 19printf("마지막 사람의 키: %d cm \n", height);

  9. 함수 간 동일 변수명은 동명이인 p.402 • 함수 간 동일 변수명은 동명이인 • [프로그램 9-2] • 학생 5명 성적에 대한 평균과 60점 이상인 합격자의 평균을 출력 • main 함수의 sumcompute_ave함수의 sum → 변수명은 같지만 완전히 다른 변수 → 함수 간 독립성 보장 → 함수 간에같은 변수명을 마음놓고 작명하여 사용 가능

  10. 9-2 함수 간 동일한 지역 변수명 사용 예 p.402 6 int main() 7 { 8 int i; 9 int pass = 0, sum = 0; // 합격자 수, 합격자 점수의 합 10 int score[N] = {93, 82, 49, 55, 75}; // N명의 점수 13 printf("전체 평균: %.1lf \n", compute_ave(score)); 16 for (i=0; i<N; i++) 17 { 18 if (score[i] >= 60) 19 { 20 sum += score[i]; 21 pass++; 22 } 23 } 24 printf("합격자의 평균: %.1lf \n", (double) sum /pass); 26 return 0; 27 } 9행 sum의 참조 영역 • 30 double compute_ave(int ary[N]) • 31 { • 32 int i, sum = 0; • 33 • 34 for (i=0; i<N; i++) • 35 sum += ary[i]; • 36 • 37 return (double)sum / N; • 38 } 32행 sum의 참조 영역

  11. 9.2 전역 변수 p.407 • 전역(global) 변수 • 블록 밖(함수 밖)에서 선언한변수 • 모든 영역(프로그램 전체)에서 참조할 수 있는 변수 • 정확히는 변수를 선언한 이후로 어디서나 참조 가능 →프로그램 상단에 선언하는 것이 편리 • 프로그램 실행 시작부터 종료까지 기억장소 차지 • 지역 변수는 블록이 끝나면 주기억장치에서 제거됨

  12. 9.2 전역 변수 p.405 • 전처리기 지시자 • 사용자 정의 함수의 원형 선언 • 자료형 전역 변수1 ; • int main( ) • { • … • } • int function1( … ) • { • … • } • 자료형 전역 변수2 ; • double function2( … ) • { • … • } • 전역 변수 1의 참조 영역 • 프로그램 전체에서 사용하는 것이 목적이므로 관습적으로 main함수 이전에 프로그램 상단에 선언함 • 전역 변수는 자동으로 0으로 초기화됨 필요하다면 다른 값으로 직접 초기화 가능 전역 변수 2의 참조 영역 function2의 지역 변수의 참조 영역

  13. 9.2.1 인수로 전달할 필요가 없는 전역 변수 p.407 전역 변수는 모든 함수에서 참조 가능 →인수 전달이 필요 없음 • [프로그램 9-5] • [프로그램 8-3]: main의지역 변수 n1, n2 중 큰 값을 구하기 위해 함수로 n1, n2를 인수로 전달  main의 모든 지역 변수를 전역 변수로 선언하여 인수를 생략하자. 17 int main() 18 { 19 int n1, n2, max; : 24 // find_larger 함수 호출 25 max = find_larger(n1, n2); 26 29 return 0; 30 } • 4 int find_larger(int first, int second) • 5 { • 6 int larger; • 7 • 8 if (first > second) • 9 larger = first; • 10 else • 11 larger = second; • 13 return larger; • 14 }

  14. 9-5 전역 변수만 사용하도록 수정 p.407 3 int find_larger(); // 함수 원형 선언 5 int n1, n2, max; // 전역 변수 선언 6 7 int main() 8 { 9 printf("첫째 정수? "); scanf("%d", &n1); 10 printf("둘째 정수? "); scanf("%d", &n2); 11 13 max = find_larger(); 14 15 printf("n1=%d, n2=%d 중 큰 값은 %d \n", n1, n2, max); 16 17 return 0; 18 } 20 // 전역 변수 n1, n2 중 큰 값을 반환하는 find_larger 함수 21 int find_larger() 22 { 23 if (n1 > n2) 24 return n1; 25 else 26 return n2; 27 } find_larger 함수에서도 n1, n2 변수를 참조할 수 있으므로 인수로 전달할 필요가 없다.

  15. 9.2.2 만능 해결사가 아닌 전역 변수 p.408 • 전역 변수의 장단점 • 장점 • 함수 간 인수 전달이 필요 없다. • 기억 공간을 효율적으로 사용 • 단점 • 다양한 인수에 대해 같은 기존의 함수를 활용할 수 없다. → 함수의 재사용성이 낮아짐 • [프로그램 9-6]의 문제점 • find_larger 함수는언제나 전역 변수 n1과 n2중 큰 값만 구하므로 main의 지역변수 width와 height 중큰 값을 구하고 싶을 때 find_larger(); 호출로는불가능 • 부작용(side-effect) 발생가능 • find_larger 함수에서 전역 변수의 값을 변경하면 그 결과가 모든 함수에 미침 • 지역 변수를 인수로 전달하는 것이 바람직: [프로그램 9-7]

  16. 9-6 find_larger 함수가 범용 함수가 될 수 없는 예 p.409 • 28 int find_larger() • 29 { • 30 if (n1 > n2) • 31 return n1; • 32 else • 33 return n2; • 34 } 5 int n1, n2, max; // 전역 변수 선언 6 7 int main() 8 { 9 int width, height; // main 지역 변수 : // n1, n2 입력받기 15 max = find_larger(); 16 printf("n1=%d, n2=%d 중 큰 값은 %d \n", n1, n2, max); 17 18 // main의 width와 height 중 큰 값을 구하여 max에 저장하기 19 width = n1 * 4; 20 height = n2; 21 max = find_larger(); 22 printf("width=%d, height=%d 중 큰 값은 %d \n", width, height, max); 24 return 0; 25 } n1, n2 중 큰 값을 구함 → width와 height 중 큰 값 구하기에 사용불가

  17. 9-7 인수 전달을 통한 문제점 해결 p.410 • 27 // 전돨된 두 값 중 큰 값 반환 함수 • 28 int find_larger(int first, int second) • 29 { • 30 if (first > second) • 31 return first; • 32 else • 33 return second; • 34 } 5 int n1, n2, max; // 전역 변수 선언 6 7 int main() 8 { 9 int width, height; : 14 // 전역 변수 n1과 n2 중 큰 값 구하기 15 max = find_larger(n1, n2); 16 printf("n1=%d, n2=%d 중 큰 값은 %d \n", n1, n2, max); 17 18 // main의 width와 height 중 큰 값 구하기 19 width = n1 * 4; 20 height = n2; 21 max = find_larger(width, height); 22 printf("width=%d, height=%d 중 큰 값은 %d \n", width, height, max); 23 24 return 0; 25 }

  18. 9.7.1 연 세금 계산하기: 지역 변수와 전역 변수 활용하기 p.423 • 문제 • 입력; main 함수에서 월 급여 입력 • 출력: 올 해 총 세금 계산한 세금 내역서 • 분석 • 월 급여 salary: 전역 변수로 선언 → 인수 전달 없이 모든 함수에서 참조 • 최종 세금 부과액 tax= 세금 부과 대상액 × 과세율 • 함수 int compute_total_salary( ) • 연 급여 구하는 함수 • 연 급여= 12달 총 급여액 + 연 보너스 (연 급여 - 세금 공제액) 세금 공제액: 천만원 월 급여가 500만원 이상: 5% 250만원 이상 500만원 미만: 3% 250만원 미만: 2% 월 급여의 300% 월 급여 × 12

  19. 9.7.1 연 세금 계산하기: 지역 변수와 전역 변수 활용하기 p.423 • 함수 intcompute_tax(int amount) • 최종 세금 부과액 구하는 함수 • 최종 세금 부과액 = 세금 부과 대상액 amount × 과세율 tax_rate • 함수 voiddisplay_tax_returns(int tot_salary, int tax_target, int tax) • 전달된 연 급여, 세금 부과 대상액, 최종 세금과 전역 변수 salary에 저장된 월 급여를 이용해 적당한 형식에 맞추어 세금 내역서 출력 main에서 전달함 이 함수에서 정해둔 값

  20. 9-12 전역 변수 월 급여를 이용한 연 세금 계산 p.424 3 int compute_total_salary(); // 연 급여 계산 4 int compute_tax(int amount); // 최종 세금 계산 6 void display_tax_returns(int tot_salary, int tax_target, int tax); 7 8 int salary; // 월 급여를 전역 변수로 선언 9 10 int main() 11 { 12 int exemption = 10000000; // 세금 공제액 13 int total_salary, tax_target, tax; // 연 급여, 세금 부과 대상액, 최종 세금 14 15 printf("월 급여는? "); scanf("%d", &salary); // 월 급여 입력 16 17 total_salary = compute_total_salary(); // 연 급여 계산 18 tax_target = total_salary - exemption; // 세금 부과 대상액 계산 19 tax = compute_tax(tax_target); // 세금 부과 대상액으로부터 최종 세금 계산 21 ` 22 display_tax_returns(total_salary, tax_target, tax); 23 24 return 0; 25 }

  21. 9-12 전역 변수 월 급여를 이용한 연 세금 계산 p.424 27 // 월 급여와 연 보너스율을 이용해 연 급여를 계산하는 함수 28 int compute_total_salary() 29 { 30 int bonus_rate = 300; // 연 보너스는 월급의 300%임을 의미 31 32 return (salary * 12) + (int)(salary * bonus_rate * 0.01); 33 } 34 35 // 최종 세금 부과 대상액 amount로부터 최종 세금을 계산하는 함수 36 int compute_tax(int amount) 37 { 38 int tax_rate; // 세금 과세율 39 40 if (salary >= 5000000) 41 tax_rate = 5; // 과세율이 5%임을 의미 42 else if (salary >= 2500000) 43 tax_rate = 3; 44 else 45 tax_rate = 2; 46 47 return (int)(amount * tax_rate * 0.01); 48 }

  22. 9-12 전역 변수 월 급여를 이용한 연 세금 계산 p.424 50 // 전달된 세금 관련 정보를 이용해 세금 내역서 출력하기 51 void display_tax_returns(int total_salary, int tax_target, int tax) 52 { 53 printf("\n >>> 세금 내역서 <<< \n"); 54 printf("-------------------------------\n"); 55 printf("연 급여 : %8d원 \n", total_salary); 56 printf("세금 부과 대상액 : %8d원 \n", tax_target) ; 57 printf("최종 세금 부과액 : %8d원 \n", tax); 58 }

  23. 9.3 자동 변수 p.411 • 변수의 지속 기간(duration) 또는 수명(lifetime) • 변수에 할당된 기억장소가 존재하는 기간 • 변수의 기억장소는 프로그램 시작부터 끝까지 존재하는 것이 아니라 변수 선언 방법에 따라 존재 기간이 달라짐 • ‘변수의 수명이 끝났다’→ ‘변수의 기억장소가 존재하지 않는다 ‘→ 해당 변수를 사용(참조)할 수 없다.

  24. 9.3.1 자동 변수의 선언과 지속 기간 p.412 • 자동 변수 • 변수의 지속 기간이 함수/블록의 실행 시작부터 끝까지로 한정 • 블록 시작 시 기억장소 할당, 블록 종료 시 기억장소 해제 → 참조 불가 • 선언 시 자료형 앞에 auto 예약어를 붙임 • auto는 생략 가능 • 지금까지의 지역변수는 모두 자동 변수 • 자동 변수 선언 반환형 함수명(매개변수선언목록) { auto 자료형 자동변수명; : } 생략 가능 ㈜ 비주얼 C++ 2010에서 ‘auto’는다른 용도의 키워드로 사용되므로 파일의 확장자를 ‘*.c’로 해야만 에러 없이 컴파일된다.

  25. 9.3.2 변수의 기억장소 할당과 자동 초기화 p.412 • 전역 변수의 저장 위치 및 초기화 • 자료 영역에 저장되며 프로그램 실행 기간 내내 존재 • 자동으로 0으로 초기화 • 자동(지역) 변수의 저장 위치 및 초기화 • 스택(stack) 영역에 저장되며 함수(블록) 실행이 끝나면 제거됨 • 자동으로 초기화 되지 않음 • 초기화 하지 않을 경우 이전의 값 즉 쓰레기 값(garbage value)을 가지므로 반드시 초기화가 필요

  26. 9-8 전역 변수의 자동 초기화와 지역 변수의 초기화 필요성 p.413 5 int global_sum; // 전역 변수 선언 6 7 int main() 8 { 9 auto int i; // 자동(지역) 변수 선언 12 for (i=1; i<=10; i++) 13 global_sum += i; 15 printf("1~10의 합 global_sum: %d\n", global_sum); 16 17 sum_to_10(); 19 return 0; 20 } 22 23 void sum_to_10() 24 { 25 auto int i, local_sum;// 자동(지역) 변수 26 28 for (i=1; i<=10; i++) 29 local_sum += i; 30 31 printf("1~10의 합 local_sum : %d\n", local_sum); 32 } 쓰레기 값 2025137940에 1부터 10까지 누적한 결과 값 ㈜ 이 결과는 ‘release’ 모드에서 실행한 것이며, ‘debug’ 모드에서는 29행에서 local_sum이 초기화되지 않고 사용되므로 실행이 중단됨

  27. 9.4.1 정적 지역 변수 p.414 • 정적(static) 지역변수 • 블록 안에서만 참조 가능하나 이전 호출 결과가 유지됨 • 지속 기간: 전역 변수처럼 프로그램 시작부터 끝까지 • 전역 변수의 부작용을 줄이는 효과 • 변수가 선언된 함수에서만 값을 변경할 수 있으므로 • 정적 지역 변수 선언 반환형 함수명(매개변수선언목록) { static자료형 정적변수1 = 초깃값; static자료형 정적변수2; : } • 이 선언 부분은 함수가 처음 호출될 때 한 번만 실행됨 → 이 함수의 두 번째 호출부터는 실행되지 않으므로 이전 호출에 의해 저장된 값이 계속 유지됨 • 초깃값이 없으면 자동으로 0으로 초기화됨

  28. 9.4.2 정적 전역 변수 p.418 • 정적 전역 변수 • 함수 밖에서 선언한 정적 변수 → 프로그램 전체에서 참조 가능 • 지속 기간: 전역 변수처럼 프로그램 시작부터 끝까지 • 전역 변수와의 차이점 • 한 프로그램이 여러 소스 파일로 나눠진 경우 • 전역 변수: 다른 소스 파일에서도 참조 가능 • 정적 전역 변수: 정적 전역 변수가 선언된 소스 파일에서만 참조 가능 • 정적 전역 변수 선언 static자료형 정적전역변수1 = 초깃값; static자료형 정적전 변수2; 함수의 정의 함수의 정의

  29. 9.5 외부 변수 p.420 • 외부 변수 선언 • extern 자료형 변수명 ; • 다른 소스 파일에서 선언된 전역 변수를 이 소스 파일에서도 전역 변수로 사용하고 싶을 때 외부 변수로 선언해야 함 int global; extern int global; main 함수 정의 global을 전역 변수로 사용 가능 s2_f1 함수 정의 global을 전역 변수로 사용 가능 s3_f1 함수 정의 global을 전역 변수로 사용 불가능 s1_f1 함수 정의 global을 전역 변수로 사용 가능 s2_f2 함수 정의 global을 전역 변수로 사용 가능 source1.cpp source2.cpp source3.cpp

  30. 9.6 레지스터 변수 p.421 • 레지스터(register) • CPU안의 메모리 → 주기억장치보다 참조 속도가 훨씬 빠름 • 레지스터 변수 • 주기억장치가 아닌 레지스터를 할당받는 변수 • 많이 참조되는 변수를 레지스터 변수로 선언함으로써 실행 속도를 개선 • 레지스터 개수의 한정 → 실행시점에 레지스터에 할당할 수 없으면 주기억장치에 할당됨 • 레지스터 변수 선언 register 자료형 레지스터변수명; register int sum, i; • [프로그램 9-11] 중첩 for문에서, 더 자주 변경되는 안쪽 for문의 제어 변수 i와 space를 레지스터 변수로 선언함

  31. 9-10 전역, 지역(자동), 정적 변수 및 프로그램 구성요소의 배치 예 p.418 1 #include <stdio.h> 2 3 void find_PW(); 4 void find_ID(); 5 6 char title[10] = "Quiz"; // 게임명, 전역 변수 7 8 static int count_service; // 총 서비스 요청 횟수, 정적 전역 변수 9 10 int main() 11 { 12 int service; // 사용자가 요청한 서비스 번호, main의 지역 변수 14 do 15 { 16 printf("\n <<< 1. ID 찾기 2. PW 찾기 3. 종료하기 >>> \n"); 17 printf(" 원하는 서비스 번호를 입력하세요(1~3) "); 18 scanf("%d", &service); 20 switch (service) 21 { 22 case 1: find_ID(); break; 23 case 2: find_PW(); 24 } 25 } while (service != 3);// 3. 종료하기를 선택하지 않는 한 계속 반복하기 27 return 0; 28 } • ID 찾기와 PW 찾기 서비스 요청 횟수를 계산하는 예제용 프로그램

  32. 9-10 전역, 지역(자동), 정적 변수 및 프로그램 구성요소의 배치 예 p.418 31 void find_ID()// 아이디 찾기 서비스 함수 32 { 33 static int count_ID; // 함수의 호출 횟수를 저장, 정적 지역 변수 34 35 count_ID++; // find_ID 함수가 호출될 때마다 1씩 증가 36 count_service++; // 전체 서비스 요청 횟수를 1 증가 37 38 printf("\n %s 게임 방문 중 ", title); 39 printf("총 전체 서비스 요청 %d번 중 %d회째 ID 찾기 요청입니다. \n", 40 count_service, count_ID); 41 } 43 44 void find_PW()// 비밀번호 찾기 서비스 함수 45 { 46 static int count_PW;// 이 함수의 호출 횟수를 저장하는 정적 지역 변수 선언 47 48 count_PW++; // find_PW 함수가 호출될 때마다 1씩 증가 49 count_service++; ` 50 51 printf("\n %s 게임 방문 중 ", title); 52 printf("총 전체 서비스 요청 %d번 중 %d회째 PW 찾기 요청입니다. \n", 53 count_service, count_PW); 54 }

  33. 9-10 전역, 지역(자동), 정적 변수 및 프로그램 구성요소의 배치 예 p.418

More Related