1.변수는 각각 생존 주기란게 있는데 변수를 만들땐 함수 밖,함수 안에 자유롭게 만들 수 있지만 이 변수가 유효한 효과를 내는 범위는 자유롭지가 않다.변수가 죽을 수도 있는 것이다.
함수 내에서 선언한 변수는 그 함수내에서만 살아있다.손쉽게 말해 함수마다 있는 중괄호를 기준(=범위,scope)으로 변수의 생명주기를 판단하면된다.
함수 내에서 사는 변수 = 지역변수
(블록 안에서 선언된 변수, 블록 = {}로 둘러쌓인 영역)
main함수를 포함한 함수 밖에서 사는 변수 = 전역 변수
-> 모든 함수에 가져다 쓸 수 있음.프로그램이 시작할때부터 끝날때까지 살아있다고 보면된다.즉 main이 시작하면서 리턴할때까지 살아있는것 이상
(단,여기서 모든 함수라는 것은 파일 하나 내에서만 유효한 것!
즉 보통 전역 변수는 함수외에서 선언된 변수로 파일 내 변수다.
모든 파일의 전역변수인지 한 파일의 전역변수인지 이런걸 구별해야됨)
전역변수의 쓰임 예시 : 원하는 함수가 몇 번 실행되었는지 알고싶으면 count란 함수로 전역 변수 선언 후 각 함수에 넣어서 값을 공유할 수 있음(구구단이면 단이라는 입력값에 따라 카운트값을 가질 수 있음)
즉 공유하고싶거나 첨부터 끝까지 살아있으면 좋겠다는것들을 전역변수로 하기
그럼 전역변수로 쓰는게 편한게아닐까싶지만 두가지 단점이 있다.
변수가 첨부터 끝까지 살아잇으니 그만큼 메모리가 유지되어 나중에는 메모리 부족의 현상을 일으킨다.그렇기에 변수들 중 역할이 끝난 변수들은 굳이 가지고있는게 아니라 메모리를 없애는게 맞다. 그러기에 이런 변수들을 지역변수로 써야한다.
또한 전역변수를 과도하게 쓰면 동일명의 변수들이 지역변수로부터의 변수인지 전역변수로부터의 변수인지 햇갈림
편하다고 전역변수를 무분별하게 사용하면안된다.
전역변수는 따로 초기화를 안해줘도 자동으로 초기화가 된다는 장점이 있음
만약 main 안에 다른 함수 안 변수는 main내에선 자유롭게 살아있는가? -> x.딱 그 속한 함수 내에서만 살아있음
void testfunc(int a)
{
.....
}
이 코드에 a도 지역변수이다. 괄호 밖이여서 전역변수로 보일 순 있지만 함수의 매게변수도 지역변수이다.(함수랑 수명을 같이하니깐)
a.함수의 인수로 변수를 가져오는 방법(=즉 매게변수로 가져오는 방법)
예로 들어, 아래 코드가 있다고 가정해보면
void testfunc()
{
.....
.....
.....
}
int main()
{
.....
.....
.....
}
내가 만약 main 함수에 int num = 3;을 선언했다고하면 그걸 testfunc 함수에 넘길 수 있냐? -> 못넘긴다.
int main()
{
.....
.....
.....
int num = 3;
}
못넘겨도 넘길 수 있는 방법이 있는데
void testfunc(int a)
{
a;
.....
.....
.....
}
이렇게 a라는 변수 선언을 하고 이걸 통해 num안에 있는 데이터값을 받아올 순 있다.
main 함수에서 testfunc를 호출할 때, 원래 있던 num을 아래와 같이 넣는다고 가정했을 때
int main()
{
.....
.....
.....
int num = 3;
testfunc(num);
}
num값이 위 testfunc 함수로 넘어가는 것 같지만 사실 그게 아니라, 변수를 넘겨준 게 아닌 안에 들어있는 '3'이란 값이 testfunc로 넘어가는 것이다.
num이랑 위 a가 결과(동일값)는 같더라도 다른 존재임을 명심해야된다.변수가 넘어간게 아니라 안에 있는 값이 넘어간 것이니깐
그리고 다를 수 밖에 없는게 a변수는 testfunc가 끝나면 생존주기가 끝나 사라진다.만약 둘이 같다고 하면 a가 사라질 때, num도 같이 사라져야된다.호출할 때 넘겨준다해서 그 변수가 살아있는게 아니고 값만 넘겨주는 것이다.
b.함수의 반환값으로 넘기는 방법
위 testfunc 함수에 return a; 라고 써주면 'a'에 있는 값을 그 값을 다른 함수에 쓸 수 있다.
(이때 리턴은 a 자체를 넘겨주는게 아니라 복사해서 밖으로 내보내는것을 명심)
결론
이 두 방법에서 제일 중요한 것은 변수 자체는 함수내에서 살아있기에 변수 자체를 넘긴다는 것은 불가능하고 그 안에 있는 값을 넘겨준다는 것이다.(포인트에서 중요한 개념)
"함수에 변수를 넣어준다"는 것은
변수를 여기에다가 옮겨준다(x)
변수가 가지고 있는 값을 옮겨준다.(o)
3.같은 지역변수끼리는 이름이 같아도 상관없다.어차피 지역변수라는게 자기지역끝나면 사라지니깐 반복해서 써도되는거임
ex) for()문 밑 for()문에 동일명 변수 가능
4.반복문 중첩으로 쓸때 전역변수로 쓰게되면(그럴일은 없겠지만)
불상사가 일어난다.
int i;
int main(void)
{
for(i = 0;i < 5; i++)
{
f();
}
return 0;
}
void f(void)
{
for(i = 0 0;i< 10; i++)
printf("#");
}
결과 : ########## 출력
위 코드는 #이 10개씩 5줄 출력되는 코드인데 결과는 보는것과 같이 한줄만 출력되었다.이유는 바로 전역변수 때문인데 컴퓨터가 for문의 i를 전역변수의 i인지 지역변수의 i인지 구분을 못해서다.작동시키면 첫 for문에서 i가 0이 되고 두번째 for문에선 i가 0이기에 # 1개부터 10개까지 입력이되고 9에서 1이 증가되어 10이 넘어간다.그리고 그 '10'이 for문 작동하는 방식으로 증감식으로 넘어간다.그래서 11이 되고 i=0은 첫번째만 실행되니깐 넘어가고 조건식을 보니깐 거짓이기에 반복문이 작동안하고 종료가 되기때문이다.
이런일이 없도록 각 지역변수를 설정해줘야된다.