7강 함수와 기억 클래스 2
1. 매개변수 사이의 자료전달
값에 의한 자료전달 (call by value)
-기본적인 자료전달 방법
- 실 매개변수와 형식 매개변수 사이에 값의 전달
-호출한 함수의 실행이 끝난 다음 전달받은 값을 되돌려 받지는 못한다.
참조에 의한 자료전달(call by reference)
-호출함수와 피 호출함수의 매개변수 값을 서로 교환할 수 있는 자료전달 방법
-값을 전달하는 것이 아니라 실 매개변수의 값이 들어있는 주소 값이 전달된다.
값에 의한 자료전달 방법
함수호출(실 매개변수) -> 자료전달(값 전달) -> 함수정의(형식 매개변수)
/* 값에 의한 자료전달 방법 예 */
#include <stdio.h>
void swap(int x, int y);
void main() {
int a = 3, b = 5;
print("호출전 a = %d, b = %d\n", a, b);
swap(a, b);
/* 호출되기 전과 값이 같다.
피호출 함수의 값의 변화는 실매개변수에 영향을 주지 않는다. */
print("호출후 a = %d, b = %d\n", a, b);
}
void swap(int x, int y) {
int temp;
temp = x;
x = y;
y = temp;
printf("함수내 x = %d, y = %d\n", x, y);
}
/ * 결과값
호출전 a = 3, b = 5
함수내 x = 5, y = 3
호출후 a = 3, b = 5
*/
값에 의한 자료전달 과정
기억공간 기존 a와 b => 함수 호출시 x,y 전달 => 함수 실행시 돌아감
참조에 의한 자료전달 방법
fcn1(&a, &b); -> 함수호출(실 매개변수)
...
int fcn1(int *X int *y) -> 함수정의(형식 매개변수)
(&:주소연산자 *:내용연산자)
/*참조에 의한 자료전달 방법 예*/
#include <stdio.h>
void swap(int x, int y);
void main() {
int a = 3, b = 5;
printf("호출전 a = %d, b = %d\n", a, b);
swap(&a, &b); //함수 호출
printf("호출후 a = %d, b = %d\n", a, b);
}
void swap(int *x, int *y) {
int temp; // 두 변수 a와 b의 값을 서로 바꿈
temp = *x;
*x = *y;
*y = temp;
printf("함수내 x = %d, y = %d\n", *x, *y);
}
/*
호출전 a = 3, b = 5
함수내 x = 5, y = 3
호출후 a = 5, b = 3
*/
참조에 의한 자료전달 과정
변수 a, b => 함수 호출시 주소를 x, y 전달 => 함수 실행 (해당 주소의 내용을 변경) => 함수 복귀시 값이 변경
-참조에 의한 자료전달은 실제 값이 변한다.
2. 기억클래스
-변수를 기억공간의 특정영역에 할당하는 방법
-즉, 각 변수의 유효범위와 존속기간을 설정
변수의 사용위치에 따라
1)지역변수(local variable)
특정 범위 내에서만 통용되는 변수
-선언된 블록이나 함수 내에서만 사용 가능
-함수에서 사용되는 매개 변수도 해당
2)전역변수
-함수 밖이나 외부파일에서 선언되어 프로그램 전체에 걸쳐 사용될 수 있는 변수
지역변수와 전역변수의 유효범위
int x, y; //변수 x,y는 프로그램 전체에서 사용 가능한 전역변수(함수외부선언)
long fcn1(int m, int n){ // 지역변수 m, n
...
x++, y--;
m++, n--;
...
}
void fcn2(){
int m, n;
...
}
void main(){
int m, n;
long x;
...
x = fcn1(10, 20);
fcn2();
...
}
/*지역변수의 사용 예1 */
#include <stdio.h>
void fcn1();
void main() {
int i = 10;
printf("\n main i = %d", i);
fcn1();
printf("\n main i = %d", i);
}
void fcn1() {
int i;
i = 20;
printf("\n fcn1 i = %d", i);
}
//지역변수로서 각각 i값이 다름
/*지역변수의 사용 예2 */
#include <stdio.h>
void main() {
//블록 A
int x = 2, y = 4;
printf("A: x = %d, y = %d\n", x, y);
{// 블록 B
int x;
x = 5;
y++;
printf("A: x = %d, y = %d\n", x, y);
}
printf("A: x = %d, y = %d\n", x, y);
}
/*
A: x = 2, y = 4
A: x = 5, y = 5
A: x = 2, y = 5
*/
/*전역변수의 사용 예*/
#include <stdio.h>
void fcn1();
int x; // 전역변수 가급적 프로그램 선두에 위치, 초기화 안하면 0으로 자동 초기화
void main() {
printf("\n 1) x = %d", x);
fcn1();
printf("\n 2) x = %d", x);
}
void fcn1() {
x++; // 전역변수
}
/*
1) x = 0
2) x = 1
*/
전역변수 지역변수의 비교
-동일 범위 내에서는 지역변수가 우선
-전역변수의 선언은 프로그램 선두에 위치
가급적 지역변수를 사용하는 것이 효율적
-함수의 독립성 향상
-디버깅 효율 향상
-기억 공간 절약
변수의 기억클래스 종류
-변수의 초기화, 존속기간 유효범위에 따라 구별
형식: 기억클래스 자료형 변수명;
기능: 기존의 변수 선언문에 기억클래스만 기입
-선언된 변수에 저장된 자료는 해당 기억영역에 놓이게 됨.
자동변수(auto)
-함수 실행시 만들어지고, 실행이 끝나면 기억공간이 제거됨
- 예약어 auto를 사용(생략가능)
- 통용 범위는 변수가 선언된 블록이나 함수 내로 한정
- 지역변수에 해당
- 초기화 필요
/* 자동변수의 사용 예 */
#include <stdio.h>
void main() {
int i = 1; // auto 생략가능
auto int j = 2;
{ //블록1
int i = 3; // 자동변수로서 블록 1에서만 가능
{ //블록2
int i = 4; // 자동변수
printf("블록 2의 i = %d\n", i);
printf("블록 2의 j = %d\n", j);
}
printf("블록 1의 i= %d\n", i);
}
printf("void main() 함수내의 i = %d\n", i);
}
정적변수
-기억영역이 프로그램 끝날 때까지 유지
- 예약어 static을 사용
- 전역 변수에 해당
- 변수의 값은 프로그램 실행 중 계속 유지
- 초기화 없으면 0으로 초기화됨
/*정적변수의 사용 예1*/
#include <stdio.h>
void main() {
int a = 10;//자동변수 선언
static int b = 20; // 정적변수 선언
{
int a = 5; // 자동변수로서 블록 벗어나면 소멸
printf("a = %d b = %d\n", a, b);
}
printf("a = %d b = %d\n", a, b);
}
/* 정적변수2 */
#include <stdio.h>
void main() {
int i;
i = 0;
while (i < 3) {
test();
i++;
}
}
test() {
auto int a = 0;
static int s = 0; // 정적변수 증가함
printf("auto = %d, static = %d\n", a, s);
++a;
++s;
}
외부변수
-함수의 외부에서 선언
-예약어 extern 을 사용
-전역 변수에 해당
- 초기화가 없으면 0으로 초기화 됨
- 다른 파일에서 외부변수로 선언된 변수의 값을 참조할 수 있다.
/* 외부변수 사용 예1*/
#include <stdio.h>
int i = 10;
int j = 20;
void main() {
// i 외부변수 선언(생략가능, 변수i가 선언되면 선언된 위치 이하부터 그 값이 유호하기 때문)
extern int i;
extern int k;
//외부변수 선언(생략불가, 변수k가 범위 바깥에 있으므로)
int j = 100;
printf("i = %d\nj = %d\nk = %d", i, j, k);
}
/* 외부변수2*/
// 5-13.c
#include <stdio.h>
#pragma warning(disable:4996)
void extern_ex();
char s[100];
void main() {
printf("문자열을 입력하세요 : ");
scanf("%s", s);
printf("입력 문자열은 %s는 전역변수 s에 저장\n", s);
extern_ex();
}
// 5-13_1.c
#include <stdio.h>
extern char s[];
void extern_ex{
printf("외부변수 s값은 %s입니다.\n",s)
}
레지스터변수
-cpu 내의 레지스터에 자료를 저장할 때
- 예약어 register사용
- 자동 변수와 동일한 속성
- 프로그램의 실행속도 증가 목적으로 사용
(주로 반복문에서 카운터변수로 사용)
/* 레지스터 변수 */
#include <stdio.h>
void main() {
register int i;
int sum = 0;
for (i = 0; i <= 10; ++i)
sum += i;
i -= 1;
printf("i = %d sum = %d", i, sum);
}
int k = 50;