c언어 - 포인터와 배열

Sorbet·2021년 2월 23일
0

1) C언어의 메모리 구조


이미지 출처 : http://www.tcpschool.com/c/c_memory_structure

int a[] = { 2,4,6,8,14,20,60 };
int b[] = { 1,4,2 };
int bsszi;
int main(int argc, char const* argv[]) {

int c[] = { 8,5,7 };    
int* d = malloc(sizeof(int) * 3);
d[0] = 8;
d[1] = 5;
d[2] = 7;
int* pa = &a[0];
printf("a,b,c,d각각의 주소값은\n  a:%x  b:%x  c:%x  d:%x  &bsszi:%x\n", a, b, c, d, &bsszi);
puts("전역변수>DATA, 지역변수>STACK, 동적할당>Heap, 초기화X 전역변수>BSS(ZI)\n\n");


2) 배열의 변수명은 첫번째 요소의 주소와 동일하다 완전히

printf("주소 비교 : %p %p \n", &a[0], &a);
printf("값 비교 : %d %d \n", a[0], *a);
  • 동일한 값이 출력됨을 알 수 있다.



3) 동치

  • 배열명[인덱스] 로 배열의 원소에 접근하는것과
  • 배열의 시작주소 + offset 으로 원소에 접근하는것은 완전히 동일하다
 printf("주소로 접근 : %d %d %d\n", *(a + 0), *(a + 1), *(a + 2));
 printf("배열 인덱스로 접근 : %d %d %d\n", a[0], a[1], a[2]);

4) 덧셈의 교환법칙이 성립해서 이런것도 가능하다

  • 심지어 이런 코드도 가능하다 : 2[a]
    • 뇌피셜이긴 하지만 아마도 추측컨데 a[2]라고 넣어도 어차피 C언어 내부적으로는 *(a+2) 이런 방식으로 변환하는게 아닐까 싶다
printf("*(a + 2):%d ,  *(2 + a):%d \n", *(a + 2), *(2 + a));
printf("a[2]:%d ,  2[a]:%d\n", a[2], 2[a]);

5) 동적할당(malloc)도 마찬가지

  • 위에 3번이 완벽하게 동일하므로, malloc 에서도 동작한다
int* d = malloc(sizeof(int) * 3);
d[0] = 8;
d[1] = 5;
d[2] = 7;

정리하는 테스트코드

#include <stdio.h>
#include <stdlib.h>


int a[] = { 2,4,6,8,14,20,60 };
int b[] = { 1,4,2 };
int bsszi;
int main(int argc, char const* argv[]) {

    int c[] = { 8,5,7 };    
    int* d = malloc(sizeof(int) * 3);
    d[0] = 8;
    d[1] = 5;
    d[2] = 7;

    int* pa = &a[0];


    printf("a,b,c,d각각의 주소값은\n  a:%x  b:%x  c:%x  d:%x  &bsszi:%x\n", a, b, c, d, &bsszi);
    puts("전역변수>DATA, 지역변수>STACK, 동적할당>Heap, 초기화X 전역변수>BSS(ZI)\n\n");

    printf("주소 비교 : %p %p \n", &a[0], &a);
    printf("값 비교 : %d %d \n", a[0], *a);
    puts(">> 배열명은 배열의 첫번째 요소의 주소와 동일하다\n\n");


    printf("주소로 접근 : %d %d %d\n", *(a + 0), *(a + 1), *(a + 2));
    printf("배열 인덱스로 접근 : %d %d %d\n", a[0], a[1], a[2]);
    printf("&a[2]:%p ,  (a + 2): %p \n", &a[2], (a + 2));
    puts(">> 배열의 인덱스로 요소에 접근하는것과, 주소연산을 통해 접근하는것은 완전히 동일하다 = 동치\n\n");

    printf("*(a + 2):%d ,  *(2 + a):%d \n", *(a + 2), *(2 + a));
    printf("a[2]:%d ,  2[a]:%d\n", a[2], 2[a]);
    puts(">> 아니 2[a] 이런 코드가 된다고?? 신기하지! 이게 바로 덧셈 교환법칙성립");

    
    for (int i = 0; i < 5; i++) {
        pa++;
        
        printf("value:%d , address:%p \n", *pa, pa);
    }

    free(d);
    return 0;
}
profile
Sorbet is good...!

0개의 댓글