본문 바로가기

Programming/Data Structure

[리눅스][C언어] 배열 포인터

반응형

배열은 붙어있다.

변수는 붙어있는 것이 보장되지 않는다.

 

 

 

#include <stdio.h>

int main(){
        int arryA[10];

        for(int i=0; i <10; i++){
                arryA[i]=i;
        }

        for(int i =0; i<10; i++){
                printf("arryA[%d]=%d\n",i,arryA[i]);
        }


        return 1;
}
~
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# gcc arry.c
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# ./a.out
arryA[0]=0
arryA[1]=1
arryA[2]=2
arryA[3]=3
arryA[4]=4
arryA[5]=5
arryA[6]=6
arryA[7]=7
arryA[8]=8
arryA[9]=9

 

 

#define MAX 100 이라고 선언해주는 것으로 아래와 같이 변수처럼 사용할 수 있다.

#include <stdio.h>

#define MAX 100

int main(){
        int arryA[MAX];

        for(int i=0; i <MAX; i++){
                arryA[i]=i*2;
        }

        for(int i =0; i<MAX; i++){
                printf("arryA[%d]=%d\n",i,arryA[i]);
        }


        return 1;
}
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# gcc arry.c
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# ./a.out
arryA[0]=0
arryA[1]=2
arryA[2]=4
arryA[3]=6
arryA[4]=8
arryA[5]=10
arryA[6]=12
arryA[7]=14
arryA[8]=16
arryA[9]=18
arryA[10]=20
arryA[11]=22
arryA[12]=24
arryA[13]=26
arryA[14]=28
arryA[15]=30
arryA[16]=32
arryA[17]=34
arryA[18]=36
arryA[19]=38
arryA[20]=40
arryA[21]=42
arryA[22]=44
arryA[23]=46
arryA[24]=48
arryA[25]=50
arryA[26]=52
arryA[27]=54
arryA[28]=56
arryA[29]=58
arryA[30]=60
arryA[31]=62
arryA[32]=64
arryA[33]=66
arryA[34]=68
arryA[35]=70
arryA[36]=72
arryA[37]=74
arryA[38]=76
arryA[39]=78
arryA[40]=80
arryA[41]=82
arryA[42]=84
arryA[43]=86
arryA[44]=88
arryA[45]=90
arryA[46]=92
arryA[47]=94
arryA[48]=96
arryA[49]=98
arryA[50]=100
arryA[51]=102
arryA[52]=104
arryA[53]=106
arryA[54]=108
arryA[55]=110
arryA[56]=112
arryA[57]=114
arryA[58]=116
arryA[59]=118
arryA[60]=120
arryA[61]=122
arryA[62]=124
arryA[63]=126
arryA[64]=128
arryA[65]=130
arryA[66]=132
arryA[67]=134
arryA[68]=136
arryA[69]=138
arryA[70]=140
arryA[71]=142
arryA[72]=144
arryA[73]=146
arryA[74]=148
arryA[75]=150
arryA[76]=152
arryA[77]=154
arryA[78]=156
arryA[79]=158
arryA[80]=160
arryA[81]=162
arryA[82]=164
arryA[83]=166
arryA[84]=168
arryA[85]=170
arryA[86]=172
arryA[87]=174
arryA[88]=176
arryA[89]=178
arryA[90]=180
arryA[91]=182
arryA[92]=184
arryA[93]=186
arryA[94]=188
arryA[95]=190
arryA[96]=192
arryA[97]=194
arryA[98]=196
arryA[99]=198

 

 

메모리의 해석

메모리는 항상 0101010101의 이진수로 데이터가 있을 뿐이고, 이것을 cpu 설계자가 어떻게 설계했느냐에 따라서 변수가 되거나, 포인터가 되거나, 데이터타입이 되는 등의 역할이 나뉠 뿐이다.

 

 

포인터는 뭐냐?

메모리값을 담아두는 그릇이다.

 

모든 메모리는 주소를 가지고 있다. 변수도 사실은 주소를 가리키고 있다.

 

포인터도 메모리공간을 차지하는데, 주소값을 저장한다. 그런데 포인터도 메모리공간을 차지하기 때문에 이거에 대한 주소값도 또 존재한다.

 

포인터 변수도 사실은 일반 변수와 동일하게 작동을 할 수 있지만, 약속하기를 메모리 번지수를 넣어두자고 약속을 했다.

 

 

int a=3;
pa = &a;
*pa=5;

ina a=3; 이라는 a라는 변수가 가리키는 주소번지를 0x01이라고 해보자.

 

그러면 pa 라는 변수에는 a의 주소번지가 들어간 변수가 된다.

*pa 연산은 pa에 담긴 주소번지를 따라가라는 의미로 5가 되고

a 변수 안에는 5로 대체된다..

 

#include <stdio.h>

#define MAX 100

int main(){

        int a;
        int *pa;

        a=3;
        printf("a = %d\n",a);
        printf("&a = %u\n",&a);

        pa = &a;
        printf("pa = %u\n",pa);
        printf("*pa = %d\n",*pa);
        printf("&pa = %u\n",&pa);

        *pa = 5;
        printf("(*pa = 5) = %d\n",*pa);



        return 1;
}
~
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# ./a.out
a = 3
&a = 3572263116
pa = 3572263116
*pa = 3
&pa = 3572263120
(*pa = 5) = 5
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13#

 

이중포인터

#include <stdio.h>

#define MAX 100

int main(){

        int a;
        int *pa;
        int **ppa;

        a=3;
        printf("a = %d\n",a);
        printf("&a = %u\n",&a);

        pa = &a;
        printf("pa = %u\n",pa);
        printf("*pa = %d\n",*pa);
        printf("&pa = %u\n",&pa);

        *pa = 5;
        printf("(*pa = 5) = %d\n",*pa);

        ppa = &pa;

        printf("ppa = %u\n",ppa);
        printf("*ppa = %u\n",*ppa);
        printf("**ppa = %u\n",**ppa);
        printf("&ppa = %u\n",&ppa);



        return 1;
}
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# ./a.out
a = 3
&a = 3499515044
pa = 3499515044
*pa = 3
&pa = 3499515048
(*pa = 5) = 5
ppa = 3499515048
*ppa = 3499515044
**ppa = 5
&ppa = 3499515056
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13#

 

이중포인터도 일반 포인터와 동일하다.

 

&는 그 변수의 주소값을 나타내고,

*는 그 주소값이 가리키는 값을 나타내는 것이다.

 

**는 말그대로, ppa라는 포인터 변수가 가리키는 주소인 pa 포인터 변수로 가서, pa가 가리키고 있는 변수값을 나타내라는 뜻이다.

 

요약하면, *는 변수 안에 담긴 값을 주소번지로 보라는 명령어다. 

 

변수 선언 시 *의 의미와 printf 에 사용되는 *의 의미는 조금 다르다.

 

변수 선언 시에는 주소값을 가리키는 포인터라는 데이터타입의 개념이고,

 

printf 에서는 주소값을 따라가라는 연산의 개념이다.

 

 

포인터 변수의 데이터타입 데이터 크기

#include <stdio.h>

#define MAX 100

int main(){

        int * a;
        char * b;
        float * c;
        double * d;
        short * e;

        printf("%d\n",sizeof(a));
        printf("%d\n",sizeof(b));
        printf("%d\n",sizeof(c));
        printf("%d\n",sizeof(d));
        printf("%d\n",sizeof(e));




        return 1;
}
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13# ./a.out
8
8
8
8
8
root@DESKTOP-O5CM2RJ:/project/22-c_study/04-13#

다른 데이터타입이더라도 다 8이 나온다.

 

 

32비트 컴퓨터는 4바이트가 나온다.

 

 

32비트로는 한 번에 주소번지를 읽어올 수 있는 메모리양이 4기가(4,294,967,295바이트)이다.

 

그래서 32비트 컴퓨터는 램이 4기가를 넘어갈 수가 없다. 어차피 주소할당을 그 이상 할 수 없기 때문이다.

 

 

우리가 현재 쓰는 컴퓨터는  64비트기 때문에 주소값의 데이터크기가 8바이트가 된다.

반응형