C 와 C++ 의 2D 이상의 배열에서의 차이? C++ 에서 에러나는 이유?

  • #3844246
    as 76.***.204.204 554

    1. C 에서 실행. 실행/해석/이해 문제 없음.

    #include <stdio.h>
    int main() {
      int a[3][3] = {{10,20,30},{40,50,60},{70,80,90}};
      int *p[3] = {a+0, a+1, a+2};
      
      printf("%d, %d, %d \n", *p[0], *p[1], *p[2]);
      printf("%d, %d", *(p[0]+1), *(p[2]+2));
      return 0;
    }
    아웃풋:
    10, 40, 70 
    20, 90

    2. C ++에서 실행. 실행/해석/이해 문제 많음. 해석하기 힘듦. 어레이 포인터도 아니고…이거 뭐지…

    #include <iostream>
    int main(){
    int a[3][3] = {{10,20,30},{40,50,60},{70,80,90}};
    
    // int *p[3] = {a+0, a+1, a+2};//  error: cannot convert ‘int (*)[3]’ to ‘int*’ in assignment
    //int (*p)[3][3] = {a+0, a+1, a+2};// error: scalar object ‘p’ requires one element in initializer
    int (*p[3])[3] = {a+0, a+1, a+2}; // ok. 그런데 이걸 어떻게 해석하지?
    
    std::cout << *p[0] <<" " << *p[1]<<" " << *p[2]  <<'\n';
    std::cout << p[0] <<" " << p[1]<<" " << p[2]  <<'\n';
    std::cout << **p[0] <<" " << **p[1]<<" " << **p[2]  <<‘\n';    // 이걸 어떻게 해석하나
    std::cout << (*p[0])[0] <<" " << (*p[1])[0]<<" " << (*p[2])[0]  <<'\n';  // 위와 같은데 이걸 어떻게 해석하나
    std::cout << (*p[0])[0] <<" " << (*p[0])[1]<<" " << (*p[0])[2]  <<'\n';
    return 0;
    }
    아웃풋:
    0x7ffe0de6a9a0 0x7ffe0de6a9ac 0x7ffe0de6a9b8
    0x7ffe0de6a9a0 0x7ffe0de6a9ac 0x7ffe0de6a9b8
    10 40 70
    10 40 70
    10 20 30
    • as 76.***.204.204

      1. int *p[3] = {a+0, a+1, a+2}; 이게 왜 C++ 에서는 에러가 날까? 그다지 큰 문제가 있어 보이는 문장이 아닌데…
      2. int (*p[3])[3] = {a+0, a+1, a+2}; 이거 좌변을 어떻게 해석해야 할는지… 아니면 1번 문장을 C++ 에서 에러피해서 대체할 더 좋은 문장이 있을지…

    • 테맨 69.***.60.58

      채찍파티한테 물어보삼 (Chat GPT)

    • 여기 70.***.149.131

      그냥 컴파일러 차이같음

    • 173.***.31.52

      vector<int> 씁시다 귀찮다

    • 1 73.***.60.181

      a : double pointer
      p[0],p[1], p[1]: single pointer

      int *p[3] = {a[0], a[1], a[2]}; —>; should be working

      • as 76.***.204.204

        int *p[3] = {a[0], a[1], a[2]}; —>; should be working. 컴파일 에러는 안나오지만 오리지널 배열과 다른 배열임.

        a[0] ={10,20,30} = *&a[0]
        a[1] ={40,50,60}
        a[2] ={70,80,90}

        a+0 = &a[0] 양변이 서로 동일한것을 표현한것임.
        a+1 = &a[1]
        a+2 = &a[2]

        위에서 봣듯이
        &a[0] 과 *&a[0] 은 서로 같은게 아님. 주소는 같긴 하지만.
        결론적으로
        int *p[3] = {a[0], a[1], a[2]}; 과 int *p[3] = {a+0, a+1, a+2}; 는 서로 다른 배열임. 둘다 문법적으로 틀린 정의는 아님.

    • 84 73.***.69.90

      int *p[3] = {a+0, a+1, a+2};
      애초에 이 문장에서부터 타입이 안맞았음.

      • as 76.***.204.204

        배열이 디케이 되기 때문에 우변 배열의 성분값들은 인티저 포인터 타입이므로 타입 선언이 틀리지 않음.
        a +1 을 ( 배열타입 + 정수타입) 으로 보고 타입이 서로 틀렸다고하면 안됨. 포인트 산술 개념이 적용되어 그냥 포인터 타입 임.

    • 지나가다 167.***.26.126

      C++ 쓸꺼면 vector<>같은 STL 쓰세요. 포인터 쓰지말라고 있는것임.

    • 84 73.***.69.90

      위에위에 as 글.

      a + 1은 타입이 int**인데, p의 element는 int*가 들어가야 하잖아.
      도대체 뭐라는거야.