ポインタと配列


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)銅歯

  • 配列名[インデックス]は、配列内の要素と
  • にアクセスするために使用されます.
  • アレイの開始アドレス+オフセット距離は、要素が完全に同じ
  • に近い.
     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;
    }