안 쓰던 블로그
재밌는 C 포인터 문제 7개 본문
1. 다음 프로그램의 실행결과를 예측해 보시오
# include <stdio.h>
void fun(int x) {
x = 30;
}
int main() {
int y = 20;
fun(y);
printf("%d", y);
return 0;
}
답: 20
값에 의한 호출로 main안의 y변수 값은 바뀌지 않는다
2. 다음 프로그램의 실행결과를 예측해 보시오
# include <stdio.h>
void fun(int* ptr) {
*ptr = 30;
}
int main() {
int y = 20;
fun(&y);
printf("%d", y);
return 0;
}
답: 30
주소에 의한 호출로 main안의 y변수 값이 바뀐다
3. 다음 프로그램의 실행결과를 예측해 보시오
#include <stdio.h>
int main() {
int* ptr;
int x;
ptr = &x;
*ptr = 0;
printf(" x = %d\n", x);
printf(" *ptr = %d\n", *ptr);
*ptr += 5;
printf(" x = %d\n", x);
printf(" *ptr = %d\n", *ptr);
(*ptr)++;
printf(" x = %d\n", x);
printf(" *ptr = %d\n", *ptr);
return 0;
}
답:
0
0
5
5
6
6
x를 가리키고 있는 int포인터
1번 printf는 x의 값 자체를 출력하니까 0
2번 printf는 ptr이 가리키고 있는 곳의 값을 출력하니까 0
*ptr += 5; 하면 x의 값이 +5
3번 printf는 +5되었으므로 5
4번도 5
(*ptr)++은 *ptr을 가져오고 ++하니까 x++과 같음
5번은 x++이 되었으니까 6
6번도 6인데 x가 6이 되었으니까 가리키고 있는 ptr도 6
4. 다음 프로그램의 실행결과를 예측해 보시오
가정: int - 4 bytes, char - 1 byte, pointer - 4 bytes
#include <stdio.h>
int main() {
int arri[] = { 1, 2 ,3 };
int* ptri = arri;
char arrc[] = { 1, 2 ,3 };
char* ptrc = arrc;
printf("sizeof arri[] = %d ", sizeof(arri));
printf("sizeof ptri = %d ", sizeof(ptri));
printf("sizeof arrc[] = %d ", sizeof(arrc));
printf("sizeof ptrc = %d ", sizeof(ptrc));
return 0;
}
답:
12
4
3
4
1번 printf는 arri의 크기를 출력함
arri는 4바이트*3짜리 배열이므로 12출력
2번 printf는 ptri의 크기를 출력함
arri는 12사이즈지만 그 배열을 가리키는 포인터 ptri 자체는 4바이트이므로 4를 출력한다
3번 printf는 arrc크리를 출력함
1바이트*3짜리 배열이므로 3출력
4번도 포인터 자체의 크기는 4이므로 4출력
가리키고 있는 배열과는 상관없이 포인터 자체의 크기는 고정
5. 다음 프로그램의 실행결과를 예측해 보시오
가정: float - 4 bytes
#include <stdio.h>
int main() {
float arr[5] = { 12.5, 10.0, 13.5, 90.5, 0.5 };
float* ptr1 = &arr[0];
float* ptr2 = ptr1 + 3;
printf("%f ", *ptr2);
printf("%d", ptr2 - ptr1);
return 0;
}
답:
90.5
3
ptr1은 arr배열의 [0]을 가리킴
ptr2는 ptr1+3을 가리키는데, 포인터의 덧셈연산은 주소값을 더한다
그러므호 ptr이 가리키는 arr[0]에서 3자리 뒤로 이동한 [3]를 가리키게 된다
1번 printf는 그래서 90.5가 출력된다
2번 printf에서 ptr2-ptr1 연산을 하는데 포인터의 뺄셈도 주소 뺄셈이라
ptr2이 가리키는 [3]에서 [0]을 빼니까 3출력
6. 다음 프로그램의 실행결과를 예측해 보시오
int main() {
char* ptr = "GeeksQuiz";
printf("%c\n", *&*&*ptr);
return 0;
}
답: G
이런 형태로
괄호의 맨 안에서부터 읽기 시작한다
맨 안의 ptr의 값의 주소의 값의 주소의 값이니까 G가 나온다고 생각할 수도 있고,
*&이 한 세트면 없애서 남은 *ptr의 값은 G라고 할 수도 있다
7. 다음 프로그램의 실행결과를 예측해 보시오
#include<stdio.h>
int main() {
int a;
char* x;
x = (char*)&a;
a = 512;
x[0] = 1;
x[1] = 2;
printf("%d\n", a);
return 0;
}
답: 머신에 따라 다르다
(리틀엔디안 기준) 513
(빅엔디안 기준) 16908800
풀이
리틀엔디안: 데이터를 자릿수가 작은 순서로 저장하는 방식
빅엔디안: 데이터를 자릿수가 큰 순서로 저장하는 방식
리틀엔디안 기준으로 처음에 이런 상태가 된다
x에다가 값을 대입하면
x[0]은 000000001을 대입, x[1]은 00000010을 대입
리틀엔디안 방식으로 표현하면 512+1로 513이 나온다
다른 풀이
char의 사이즈는 1바이트(8비트)니까 최대값이 이진수로 11111111인 255까지 저장 가능
메모리에 int값을 저장했을 때 char단위로 나누게 되면 255씩 끊어서 보게 된다
char은 1바이트, int는 4바이트니까
char 기준 11111111은 int기준 11111111 11111111 11111111 11111111
그러면 int기준 배열에서 최대값은 각각 255, 255<<8, 255<<(8*2), 255<<(8*3)...
이런 관점을 깔고 다시 문제를 보면
처음에 int형 a에 512가 들어갔을 때, char관점에서는 0 2 0 0 이 들어가있는 것이다
자세히 말하면 0+(2<<8)+0+0 = 512 형태
이제 x[0]=1, x[1]=2를 대입해보면
x[1]=2는 원래 2였으니까 2가 대입되어도 그대로 2
x[0]=1을 하면 첫째자리에 1이 대입되며 1 2 0 0 형태가 된다
이를 256진수로 바꾸면 513이 나온다
그러면 빅엔디안 기준이었다면?
빅엔디안이면 반대 순서인 0 0 2 0 형태로 저장된다
x[0]=1, x[1]=2를 대입하면 1 2 2 0 형태가 된다
(리틀엔디안 기준으로 x[3]=1, x[2]=2를 대입한 것과 같음)
계산해보면 16908800이 나오게 된다
문제 출처 https://www.geeksforgeeks.org/c-pointers-question-1/?ref=lbp
'알고리즘 > Algorithm' 카테고리의 다른 글
자료구조-트리 순회(전위 순회, 중위 순회, 후위 순회) (0) | 2020.06.16 |
---|---|
자료구조-트리 (트리, 이진 트리, C로 구현) (0) | 2020.06.10 |
알고리즘-스택 (C언어 배열로 구현한 스택, STL stack) (0) | 2020.05.30 |
알고리즘에서 쓰는 비트연산 (0) | 2020.05.22 |
펜윅트리로 '세그먼트 트리 느리게 업데이트 하기(Lazy Propagation)' 구현하기(2934 LRH식물 펜윅트리) (3) | 2020.04.04 |