안 쓰던 블로그

재밌는 C 포인터 문제 7개 본문

알고리즘/Algorithm

재밌는 C 포인터 문제 7개

proqk 2020. 6. 3. 18:32
반응형

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

반응형
Comments