C 17Day (20160129)
by jennysgapscanf 함수 다시보기
1 2 3 4 5 | int main(void) { int num; scanf("%d", &num); //변수 num의 주소 값을 scanf 함수에 전달 } | cs |
scnaf 함수는 변수 num의 주소값을 알아야 한다.
그래서 scnaf 함수 호출시에 변수 num의 주소 값을 전달하는 것이다.
문제
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main(void) { char num=10; int * ptr1 = # int * ptr2 = ptr1; (*ptr1)++; (*ptr2)++; printf("%d \n", num); return 0; } | cs |
문제 2
상수
정의
- 변경이 불가능한 데이터를 의미
- 한번 값을 초기화 하려면 변경 할 수 없는 공간으로 선언하면서 초기화해야 함 (선언과 동시에 초기화)
종류
- 리터널(Literal) 상수
- 심볼릭(Symbolic) 상수 = const 상수
리터널(Literal) 상수
이름이 없는 상수로 어떤 값 그 자체를 의미함
1 2 3 4 5 | int main(void) { int num = 30 + 40; // 30과 40은 상수 ... } | cs |
30과 40의 덧셈이 우선 진행되고, 그 결과로 얻어진 값을 변수 num에 초기화 한다.
그러기 위해서는 30과 40이라는 정수가 메모리상에 존재해야 한다.
그래야 CPU의 연산대상이 될 수 있기 때문!!
심볼릭(Symbolic) 상수 = const 상수
- 변수와 마찬가지로 이름을 지니는 상수
- 상수의 이름은 모두 대문자로 표시한다.
1 2 3 4 5 6 | int main(void) { const int MAX = 100; //MAX는 상수! 따라서 값의 변경 불가! const double PI = 3.1415; //PI는 상수! 따라서 값의 변경 불가! ... } | cs |
const 상수도 변수와 마찬가지로 선언만 하고 초기화하지 않으면 쓰레기 값으로 초기화 된다.
그러므로 변경하려 들 때, 컴파일 에러가 발생한다. (상수같은 경우, 무조건 선언과 동시에 초기화!)
상수를 선언하는 방법 예제
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> int main(void) { const int MAX=100; //상수는 선언동시에 초기화!!! //MAX=200; 안됨 printf("%d\n", MAX); return 0; } | cs |
포인터 변수 앞에도 사용 가능
포인터 변수가 가리키는 대상을 변경하지 않겠습니다. 라는 의미
쓰는 일 은근 있습니다. 코드가 길어지기 시작하면 바꿀 수 있기 때문에 변경되면 안되는 것들만 간혹 사용
배열에 대해서 다시 한번 살펴보자
|
|
|
|
0x0060 0x0064 0x0068 0x0072
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main(void) { int arr[3]={10, 20, 30}; printf("%p\n", &arr[0]); //주소값을 확인 하는 방법 printf("%p\n", &arr[1]); printf("%p\n", &arr[2]); return 0; } | cs |
int : 4씩 차이남
char : 1씩 차이남
double : 8씩 차이남
메모리의 배열은 1byte 형태로 할당
배열의 이름을 주소형태로 표현
= 배열의 첫번째 주소값이랑 같음
1 2 3 4 5 6 7 8 9 10 11 12 | #include <stdio.h> int main(void) { char arr[3]={10, 20, 30}; printf("%p ", &arr[0]); printf("%p ", &arr[1]); printf("%p\n", &arr[2]); printf("%p\n", arr); //배열의 형태를 주소형태로 표현 return 0; } | cs |
즉, 배열의 이름이 배열의 첫번째 요소를 가리킨다. (=배열의 첫번째 요소의 주소값이기 때문이다.)
scanf에서 배열은 왜 &를 안사용 한 건가요?
배열의 이름 자체가 주소값이기 때문이다. (=정확히는 배열의 첫번째 요소 주소값이기 때문이다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h> int main(void) { char arr[3]={10, 20, 30}; printf("%p ", &arr[0]); printf("%p ", &arr[1]); printf("%p\n", &arr[2]); printf("%p\n", arr); //배열의 형태를 주소형태로 표현 printf("%d\n", *arr); //배열에 * 사용 가능 return 0; } | cs |
배열의 값은 배열의 첫번째 요소 주소값이기 때문에
* (에스크립터) 사용하면 배열이 가리키는 값인 첫번째 주소에 있는 공간에 값을 출력하게 됨
즉, 배열도 포인터라는 의미!!!!! (배열이 포인터라는 사실을 빨리 받아 들이세요~~~)
char arr[3]={10, 20, 30};
int * ptr = &arr[0];
int * ptr = arr; //위와 같은 의미
두번째 요소가 출력될 수 있도록 하기!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> int main(void) { int arr[3]={10, 20, 30}; int * ptr=&arr[0]; printf("%p ", &arr[0]); printf("%p ", &arr[1]); printf("%p\n", &arr[2]); printf("%p\n", arr); //배열의 형태를 주소형태로 표현 printf("%d\n", *arr); //배열에 * 사용 가능 printf("%p %p %p\n", ptr, ptr+1, ptr+2); //아 포인터 연산에 1씩 올리면 4씩 올라가는 구나 printf("%d %d\n", *(ptr+1), *(arr+1)); //두번째 요소 출력....? 포인터 연산을 사용하면 됨 printf("%d %d %d\n", arr[0], arr[1], arr[2]); printf("%d %d %d\n", *arr, *(arr+1), *(arr+2)); printf("%d %d %d\n", *ptr, *(ptr+1), *(ptr+2)); printf("%d %d %d\n", ptr[0], ptr[1], ptr[2]); return 0; } | cs |
char 형태일 땐 포인터 연산 1 올리면 주소값이 1씩 오름
int 형태일 땐 포인터 연산 1 올리면 주소값이 4씩 오름
double 형태일 땐 포인터 연산 1 올리면 주소값이 8씩 오름
아~ 자료형의 크기 만큼 오르는 구나~ 라는 것을 알 수 있음
arr[i] == *(arr+i)
Q&A
자료형이랑 상관없이 크기가 4byte라고 했는데....
주소값은 다름 자료형에 영향을 받고
크기는 자료형이랑 상관없이 4byte.
포인터 변수와 배열의 이름은 완별히 동일한 개념임
그런데 왜 나누냐...? 다른 차이점이 있기 때문 자세한 차이점은 다음 수업때 알려주겠지만
맛보기식으로 알려준다면
상수형태의 포인터냐 vs 변수형태의 포인터냐의 차이점!!!
'BOX' 카테고리의 다른 글
C 19Day (20160202) (0) | 2016.02.02 |
---|---|
C 18Day (20160201) (0) | 2016.02.02 |
C 16Day (20160128) (0) | 2016.01.31 |
C 15Day (20160127) (0) | 2016.01.31 |
C 14Day (20160126) (0) | 2016.01.31 |
블로그의 정보
jennysgap
jennysgap