wau2380's playground

학생을 위한 C 언어 2.포인터와 배열 본문

학생을 위한 C/포인터

학생을 위한 C 언어 2.포인터와 배열

wau2380 2021. 6. 19. 23:29

 

복습

 

예전에 배웠던 개념들을 다시 복습합시다.

 

변수 : 데이터를 저장하는 공간

포인터: 메모리의 주소를 저장하는 변수를 포인터라고 합니다.

int a; //a 라는 이름을 가진 정수형 변수
*p; //p 라는 이름을 가진 포인터형 변수

 

시작

포인터를 다룰때, 배열이 자주 등장하게 됩니다.

C 에서는 포인터와 배열은 꽤 닮았다고 말할수 있습니다.

결론을 말하면, 배열이 내부적으로 포인터로 되어있기 때문입니다.

 


1. 배열 (Array)

 

배열(Array)이란? 동일한 타입(int,float)을 모아서 한번에 관리하기 위해서 사용하는 데이터 타입이다.

변수가 하나의 데이터를 저장하기 위함이라면 배열은 여러 개의 데이터를 하나의 변수에 저장하는것 이라고 말할수 있습니다.

int S[5]; //정수형 S 라는 이름을 가진 배열

 

위에 코드 처럼 선언하면 정수형(int)변수 5개를 만들고 S 라는 하나의 이름으로 관리하게 됩니다.

 

그럼 메모리상에서 배열은 어떤 모습일까요? 일단 배열안에 있는 변수들의 주소들을 출력해봅시다.

그리고 변수와 배열의 주소의 차이점을 한번 살펴봅시다.

#include <stdio.h>

int main()
{
  int S[5];
  printf("%d %d %d %d %d",&S[0],&S[1],&S[2],&S[3],&S[4]);
return 0;
}

[Result]

1876947972 1876947976 1876947980 1876947984 1876947988 //컴퓨터 마다 결과가 다를수 있어요

#include <stdio.h>

int main()
{
  int a,b,c,d,e
  printf("%d %d %d %d %d",&a,&b,&c,&d,&e);
return 0;
}

[Result]

1876947992 1876947988 1876947984 1876947980 1876947976//컴퓨터 마다 결과가 다를수 있어요

 

차이점을 아시겠나요? 배열은 주소가 낮은쪽에서 높은쪽으로 순차적으로 부여됬고 변수는 주소가 서로 각각

다르고 주소가 변칙적으로 부여된것을 알수있어요. (메모리는 주소는 OS(Window,Mac)이 임의로 정함)

여기서 중요한 포인트는 배열은 메모리상에서 연속된 공간을 할당받는 것입니다.

(그림 죄송합니다😭😭)

 


그럼 여기서 하나의 의문이 듭니다. 배열 S 의 주소는 뭘까?

 

생각할거 없이 다음 코드를 실행시켜 봅시다.

#include <stdio.h> 
int main()
{
  int S[5];
  printf("%d %d %d %d %d",&S[0],&S[1],&S[2],&S[3],&S[4]);
  printf("%d",&S);
return 0;
}

 

[Result]

1876947972 1876947976 1876947980 1876947984 1876947988 //컴퓨터 마다 결과가 다를수 있어요

1876947972 S의 주소

엇? S[0] 의 주소가 S 의 주소랑 같으니 배열 S의 주소는 S[0]의 주소인것을 확인할수 있습니다.

그러면 배열 S의 주소말고 배열 S가 가진 값은 무엇인지 궁금하지 않나요?

 

바로 코드를 작성해봅시다.

#include <stdio.h>
int main()
{
    int S[5];
    printf("%d",&S);
    printf("%d",S);
return 0;
}

 

[Result]

1876947972

1876947972

🤔🤔🤔 흠.. 분명 포인터는 메모리의 주소를 저장하는 변수인데

배열 S가 가진 값은 배열 자신의 주소임을 알수있습니다! 데체 이게 무슨 일이죠?? 😩😩

그러면 배열은 포인터 아닙니까? 그러면 배열 = 포인터라고 봐도 상관 없지 않을까요?


2. 배열과 포인터

 

만약 배열이 포인터와 같다면, 포인터는 가리킬수있는 주소를 마음대로 변경할 수 있습니다.

그러므로 배열도 마찬가지로 주소를 변경할수 있어야 합니다.

 

아래 코드를 봅시다.

#include <stdio.h>

int main(){

    int S[5];
    int *p;
 
    S = &p;
return 0;
}

[Result]

Computer: what are you doing!!!🤬🤬

어라?.. 배열의 주소가 포인터의 주소를 가르키지 못하네요?

그러면 포인터가 배열의 주소를 가르켜볼까요?

#include <stdio.h>

int main(){

    int S[5];
    int *p;
    p = &S;
    printf("%d",(*p));
return 0;
}

[Result]

0

S[0]의 값이 출력이 되었네요? 여기서 알수있는 점은 포인터는 배열의 주소를 가리킬수 있지만

배열은 포인터의 주소를 가리키지 못했다는 겁니다.

분명 아까는 배열 S가 값안에 주소가 들어있어서 포인터인줄 알았는데 왜 이런걸까요?


3.배열과 포인터의 차이점

 

배열과 포인터의 차이점을 정리하면 다음과 같습니다.

-포인터는 변수, 배열은 상수
-포인터 변수는 메모리를 가짐,배열은 포인터 상수로 메모리를 가지고있지 않음
-포인터는 변수이므로 가리키고있는 주소 변경 가능, 배열은 상수이므로 가리키고있는 주소 변경 불가능

 

그래서 C 언어에서는 배열은 제한적으로 사용할수있는 포인터라고도 볼수 있는것이죠

또한, 배열은 무조건 [0]번째 원소에 대한 주소를 가지고 있어야 합니다.

그래서 [1],[2] 같은 다른 원소들에 대한 위치역시 [0]번째의 주소를 기준으로 하여 계산하기 때문에

결론적으로 기준이 되는 S의 주소는 절대로 수정할 수 없습니다 (상수)

 

아래 코드를 봅시다.

#include <stdio.h>

int main()
{
  int S[5];

  *S = 1;
  *(S+1) = 2;
  *(S+2) = 3;
  *(S+3) = 4;
  *(S+4) = 5;

  printf("%d %d %d %d %d", S[0],S[1],S[2],S[3],S[4]);

return 0;
}

[Result]

1 2 3 4 5

애기하자면, S[n] 형식으로 배열의 각 원소를 다루는 것은 내부적으로 포인터를 통해 연산하는 과정으로

이뤄지게 되는것이죠! 👍🏼👍🏼👍🏼

 

어때요? 포인터와 배열 알고보면 별거 아니죠?😆😆😆😆

 

수고하셨습니다 ~~

 

 

Created by Pixochris - Freepik.com(Created by flaticon - Freepik.com)

 

 

'학생을 위한 C > 포인터' 카테고리의 다른 글

학생을 위한 C 언어 1. 포인터  (0) 2021.07.09