[C++] 문제 풀어보기[포인터, 변수] (풀이 및 설명 포함)

2024. 3. 13. 12:07Programming Language/C++

아래 링크 클릭 시 해당 본문으로 이동

포인터 문제

변수 문제

주소로 값 변경하기


포인터

전체 코드

#include <stdio.h>

int main()
{
	// 1번 문제
	short sArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    int* pI = (int*)sArr;

    int iData = *((short*)(pI + 2));

    printf("1번 문제 정답 : %d\n", iData);
    
    // 2번 문제
    char cArr[2] = { 1, 1 };

    short* pS = (short*)cArr;

    iData = *pS;

    printf("2번 문제 정답 : %d\n", iData);

	return 0;
}

나의 문제 풀이

※ 풀이 과정 및 답은 내가 생각한 대로 작성한 것이기 때문에 오답일 수도 있다.

1번 문제 (정답)

short sArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int* pI = (int*)sArr;

int iData = *((short*)(pI + 2));

printf("1번 문제 정답 : %d\n", iData);

 

short sArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

`sArr`은 short형 10묶음 배열의 이름이자 시작 주소이고, 데이터 하나의 단위는 2byte이다.

sArr 메모리

 

int* pI = (int*)sArr;

`pI`는 int형 포인터 변수로, 주소를 int로 보기 때문에 4byte 크기로 접근한다.

short형 배열 `sArr`을 int 포인터로 강제 캐스팅했다.

pI 메모리

 

int iData = *((short*)(pI + 2));

괄호를 먼저 봐야 된다.

`pI + 2` ➜ 주소를 4byte로 접근하는 `pI`로부터 2칸 이동한다.

int 포인터 변수에서 2칸 증가는 실제 주소에서는 4 × 2 = 8byte 증가를 의미한다.

그곳으로부터 short 포인터로 2byte 다음 칸에 접근하면 5를 가리키게 된다.

pI 메모리

답 : 5


2번 문제 (오답)

char cArr[2] = { 1, 1 };

short* pS = (short*)cArr;

iData = *pS;  // int iData = *pS;

printf("2번 문제 정답 : %d\n", iData);

 

char cArr[2] = { 1, 1 };

`cArr`은 char형으로 2묶음 되어있는 배열의 이름이자 시작 주소이고 크기는 1byte이다.

cArr 메모리

 

short* pS = (short*)cArr;

`pS`는 short형 포인터 변수로, 주소를 short형으로 보기 때문에 2byte 크기로 접근한다.

char형 배열 `cArr`을 short 포인터로 강제 캐스팅했다.

pS 메모리

 

iData = *pS;  // int iData = *pS;

`pS`로 접근하는데 short형이기 때문에 2byte로 접근한다.

short형으로 접근한 주소를 int형 변수 `iData`에 넣는다.

그 이후는 잘 모르겠다.

답 : 모르겠다.


정답 및 문제 풀이

콘솔 창 (1번, 2번 문제 정답)

 

1번 문제

short sArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int* pI = (int*)sArr;

int iData = *((short*)(pI + 2));

printf("1번 문제 정답 : %d\n", iData);

 

short sArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

배열의 이름이자 시작 주소인 `sArr`은 short 배열이다.

short형은 2byte 정수형이니까 데이터 하나의 단위가 2byte이다.

sArr 메모리

 

int* pI = (int*)sArr;

`sArr`은 short 포인터 주소인데 int 포인터로 강제 캐스팅 했다.

pI 메모리

 

int iData = *((short*)(pI + 2));

괄호 먼저 계산해야 되므로 `pI + 2` 먼저 연산한다.

int 포인터에 2칸 증가시켰으므로 주소값은 8byte 증가된다.

만약 short 포인터가 아니라 int 포인터로 접근했다면 4byte만큼 접근해서 원래 의도과 다르게 6을 가리키게 된다.

하지만 접근하기 전에 short 포인터로 바꿔서 2byte만큼 접근했기 때문에 5를 가리킨다.

pI 메모리

답 : 5

콘솔 창 (1번 문제 정답)


2번 문제

char cArr[2] = { 1, 1 };

short* pS = (short*)cArr;

iData = *pS;  // int iData = *pS;

printf("2번 문제 정답 : %d\n", iData);

 

char cArr[2] = { 1, 1 };

`cArr`은 char 배열이고 데이터 하나의 단위는 1byte이다.

포인터 타입은 `cArr`이 char 배열의 주소이기 때문에 char 포인터이다.

cArr 메모리

 

short* pS = (short*)cArr;

short 포인터로 강제 캐스팅했다.

short 포인터 변수 `pS` 입장에서는 첫 번째 칸에 있는 1의 시작 주소값을 받고, 자기가 가리키고 있는 곳을 short로 본다.

pS 메모리

 

이번에는 short로 바꾸지 않고 바로 주소에 접근했기 때문에 `pS`는 2byte 정수인 short로 본다.

int iData = *pS;

메모리 구조를 생각하면 각각 8bit로, 총 16bit이다.

문제에서 각각 값은 1이고 전체 2byte로 표현하면 `0000 0001 0000 0001`이다.

 

1byte(8bit)로 표현할 수 있는 최대치는 255로, bit로는 `1111 1111`이다.

여기에 1을 더하면 `1 0000 0000`이 되는데 1byte로는 앞에 1이 들어갈 자리가 없어서 0이 된다.

하지만 2byte로 전체 bit를 보면 256이 된다.

`0000 0001 0000 0000`

bit : 0000 0001 0000 0001

∴ 256 + 1 = 257

답 : 257

콘솔 창 (2번 문제 정답)


변수

전체 코드

#include <stdio.h>

void Test(int a)
{
	a = 500;
}

int main()
{
	int a = 100;   
    Test(a);
    
    printf("출력 : %d\n", a);
    
    return 0;
}

나의 문제 풀이(=정답 및 문제 풀이) (정답)

`main()` 함수에 있는 `a`와 `Test()` 함수에 있는 `a`는 다르다.

#include <stdio.h>

void Test(int a)  // a : Test() 지역에 있는 변수
{
	a = 500;
}

int main()
{
	int a = 100;  // a : main() 지역에 있는 변수
    
    return 0;
}

 

`Test()` 함수가 종료되면 결국 500은 사라지고, `void Test(int a)`의 `a`로 100을 저장해도 어차피 서로 다른 지역에 있는 변수라서 `main()` 함수의 `a`에 영향을 주지 않는다.

void Test(int a)
{
	a = 500;
}

int main()
{
	int a = 100;
    Test(a);
    
    return 0;
}

∴ `a`에는 100이 저장되어있다.

답 : 100


주소로 값 변경하기

▷ `Test()` 호출을 통해서 `main()`의 `a`값을 변경하고 싶을 때

포인터를 알기 전에는 각 함수에 존재하는 지역 변수의 스택 데이터를 서로 별개로 봤다.

함수를 호출하는 과정에서 서로 다른 지역에서 각각의 지역 상황을 모르기 때문에 다른 함수의 지역 변수를 수정하려면 주소를 이용하면 된다.

다른 지역에서 실제 변경하고 싶은 원본 데이터의 주소를 통해서 값을 변경할 수 있다.

서로 전혀 다른 스택이지만 코드에서 호출했던 변수의 주소에 접근하면 된다.

#include <stdio.h>

void Test(int* a)
{
	*a = 500;  // a의 주소에 접근해서 값을 500으로 바꾼다.
}

int main()
{
	int a = 100;   
    Test(&a);  // a의 주소를 Test() 함수에 넣는다.
    
    printf("출력 : %d\n", a);  // 출력 : 500
    
    return 0;
}

콘솔 창 (a는 500)

'Programming Language > C++' 카테고리의 다른 글

[C++] void 포인터(void*)  (0) 2024.03.14
[C++] const와 포인터  (0) 2024.03.14
[C++] 포인터(Pointer), 포인터 배열  (0) 2024.03.12
[C++] 운영 체제(OS)  (0) 2024.03.12
[C++] 분할 구현, 분할 구현 문제점  (0) 2024.03.11