scanf에서 &를 붙이는 이유C언어를 처음 공부할 때 scanf에서 &를 붙이는 이유가 가장 헷갈렸다.
처음에는 그냥 외워서 썼는데, 실제로 어떻게 동작하는지 이해하고 나니까 훨씬 명확해졌다.
scanf의 역할scanf는 사용자로부터 값을 입력받아서 변수에 저장하는 함수다.
int a;
scanf("%d", &a);
이 코드의 목적은:
a에 저장하는 것먼저 변수는 메모리 공간을 가진다.
예를 들어:
int a;
이 코드를 실행하면 메모리 어딘가에 a를 위한 공간이 만들어진다.
주소: 1000번지 (가정)
값: 아직 없음
여기서 중요한 개념이 두 가지 있다.
a → 변수에 들어 있는 값&a → 변수 a가 저장된 주소&를 붙여야 하는가scanf는 입력값을 변수에 넣어줘야 한다.
그러려면 변수의 위치(주소)를 알아야 한다.
scanf("%d", &a);
이 코드는 내부적으로 이런 의미라고 보면 된다.
a가 있는 메모리 위치에 저장해라"즉, &a를 넘겨줘야 scanf가 어디에 값을 넣어야 할지 알 수 있다.
a를 넘기면 왜 안 되는가scanf("%d", a); // 잘못된 코드
이건 왜 틀릴까?
a는 값이다 (예: 0, 쓰레기값 등)scanf는 값이 아니라 주소가 필요하다즉, scanf 입장에서는:
그래서 잘못된 동작을 하거나 오류가 발생한다.
예를 들어:
int a;
scanf("%d", &a);
사용자가 10을 입력하면:
&a → a의 주소 (예: 1000)scanf가 1000번지에 10 저장결과:
a = 10
printf와의 차이이 부분도 많이 헷갈렸던 부분이다.
printfprintf("%d", a);
ascanfscanf("%d", &a);
&aC언어 함수는 기본적으로 값을 복사해서 전달한다.
예를 들어:
void change(int x) {
x = 100;
}
int a = 10;
change(a);
이 경우 a는 바뀌지 않는다.
왜냐하면:
a의 값이 복사되어 x로 들어감a는 그대로 유지됨void change(int *x) {
*x = 100;
}
int a = 10;
change(&a);
이 경우는 a가 100으로 바뀐다.
이유:
&a → a의 주소 전달*x = 100 → 실제 a의 공간을 변경👉 scanf도 이 방식으로 동작한다
&를 안 붙일까char str[100];
scanf("%s", str);
이건 예외처럼 보인다.
이유는:
👉 배열 이름 자체가 주소 역할을 하기 때문이다
str = 배열의 시작 주소& 없이도 가능a → 변수 값
&a → 변수의 주소
scanf는 값을 저장해야 하기 때문에 주소 필요
printf는 값을 출력만 하면 되기 때문에 값만 필요
scanf는 변수의 값을 바꾸는 함수이기 때문에,
변수의 주소를 넘겨줘야 한다.