C中的类型 - int*和int*[100]有什么区别?

Ble*_*rge 12 c pointers

有点像菜鸟所以不要在这里杀了我.

以下代码之间有什么区别?

int *p;         //As i understand, it creates a pointer to an variable of size int.
int *p[100];    //Don't really know what this is.
int (*p)[100];  // I have come to understand that this is a pointer to an array. 
Run Code Online (Sandbox Code Playgroud)

Jos*_*eld 40

  1. 这是一个指向int:

    int *p;
    
    Run Code Online (Sandbox Code Playgroud)
    ??????
    ?int*?
    ??????
    
    Run Code Online (Sandbox Code Playgroud)

    它应该指向一个int类似这样的东西:

    ??????
    ?int*?
    ??????
      ?
    ?????
    ?int?
    ?????
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这是一个包含100个指针int数组:

    int *p[100];
    
    Run Code Online (Sandbox Code Playgroud)

    也就是说,它会给你100个指针.

    ????????????????????????????????
    ?int*?int*?int*?int*?int*?int*?
    ????????????????????????????????
    
    Run Code Online (Sandbox Code Playgroud)

    每个指针应该指向一个int,也许是这样的:

    ????????????????????????????????
    ?int*?int*?int*?int*?int*?int*?
    ????????????????????????????????
      ?    ?    ?    ?    ?    ?
    ????????????????????????????????
    ?int??int??int??int??int??int??
    ????????????????????????????????
    
    Run Code Online (Sandbox Code Playgroud)

    当然,他们没有理由不能同时指出同样的int事情.

    如果你想要很多可以轻松迭代的指针,你可能想要使用一个指针数组.例如,您可以动态分配对象并使每个指针指向不同的对象:

    p[0] = new int(0);
    p[1] = new int(0);
    // ...
    
    Run Code Online (Sandbox Code Playgroud)

    也许动态分配ints并不是最好的例子,但我认为这一点很清楚.

  3. 这是一个指向100的数组的指针int:

    int (*p)[100];
    
    Run Code Online (Sandbox Code Playgroud)

    也就是说,它只给你一个指针:

    ?????????????
    ?int(*)[100]?
    ?????????????
    
    Run Code Online (Sandbox Code Playgroud)

    它应该指向一个包含100 ints 的数组:

    ?????????????
    ?int(*)[100]?
    ?????????????
      ?
    ??????????????????????????
    ?int?int?int?int?int?int?
    ??????????????????????????
    
    Run Code Online (Sandbox Code Playgroud)

    当您在&数组名称上使用address-of operator()时,您将获得指向数组的指针.例如:

    int arr[100] = { /* some initial values */ };
    int (*p)[100] = &arr;
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,我已经获取了arr数组的地址,它给了我一个指向该数组的指针.如果您想要访问数组的元素,则必须首先取消引用指针:(*p)[3]将访问元素3.


边注:

永远记住,数组不是指针.正如我们刚才看到的,我们可以获取数组的地址来获取指向它的指针,就像C++中的任何其他(非临时)对象一样.数组和指针之间唯一的特殊连接是数组的名称可以隐式转换为指向数组第一个元素的指针.这意味着以下内容有效:

int arr[100] = { /* some initial values */ };
int* p = arr;
Run Code Online (Sandbox Code Playgroud)

指针p将指向第一个元素arr.请注意,p不是指向数组的指针,而是指向数组元素的指针.

(另请注意,不存在数组类型函数参数.如果您编写类似int p[]函数参数的东西,它会被编译器转换为int*.)

  • 优秀的ASCII艺术:-) (6认同)
  • @haccks [Box-drawing characters](http://en.wikipedia.org/wiki/Box-drawing_character) (2认同)

Mik*_*ike 18

听起来你可以使用螺旋规则的介绍.

从变量开始,从左到右依次"螺旋":

              +-------+
              | +--+  |             // So we have:
              | |  |  |                    p    // p     
          int * p  |  |                  * p    // p is a pointer
           ^  ^    |  |              int * p    // p is a pointer to an int
           |  +----+  |
           +----------+
Run Code Online (Sandbox Code Playgroud)

下一个:

              +--------+
              | +--+   |         p       // p
              | |  V   |         p[100]  // p is an array of 100
          int * p[100] |       * p[100]  // p is an array of 100 pointers
           ^  ^    |   |   int * p[100]  // p is an array of 100 pointers to ints
           |  +----+   |
           +-----------+
Run Code Online (Sandbox Code Playgroud)

最后,规则的一部分,首先在括号中做任何事情:

                   +-----+            
                   | +-+ |    
                   | ^ | |         ( p)       // p
              int (* p)  [100];    (*p)       // p is a pointer
               ^   ^   | |         (*p)[100]  // p is a pointer to an array of 100
               |   +---+ |     int (*p)[100]  // p is a pointer to an array of 100 ints
               +---------+    
Run Code Online (Sandbox Code Playgroud)

如果你在线/可以访问计算机,那么使用cdecl.org网站总是很有用,但是能够离线阅读代码也很重要,而这条规则可以让你做到这一点.

  • 这太棒了!我打算打印出来. (2认同)

Eri*_*ert 9

有点像菜鸟所以不要在这里杀了我

即使对于专家来说,解决C中的类型意味着什么也很棘手.别担心.

以下代码之间有什么区别?

其他答案都很好,我无意反驳.相反,这是考虑它的另一种方式.我们需要定义三件事:

  • 一个变量是支持三个操作的事情.所述操作需要的变量,并产生它的当前值.获取操作没有表示法; 你只需使用变量.所述存储操作需要一个变量和一个值,并存储在变量中的值.该地址操作需要一个变量,并产生一个指针.

  • 一个指针是支持一个操作的事情.作为前缀写入的取消引用操作*pointer接受指针并产生变量.(指针支持其他操作,如算术和索引 - 这是算术的一种形式 - 但是不要去那里.)

  • 一个阵列是支持一个操作的事.所述索引操作需要的阵列和一个整数,并产生一个可变.它的语法是后缀:array[index]

好的,现在我们来回答您的问题.宣言是什么?

int p;
Run Code Online (Sandbox Code Playgroud)

意思?表达式p是类型的变量int.请注意,这是一个变量; 你可以把东西存放到p.宣言是什么?

int *p;
Run Code Online (Sandbox Code Playgroud)

意思?表达式*p是类型的变量int.现在我们知道我们可以推断出什么p是.由于*p是取消引用并生成变量,因此p必须是指向int的指针.宣言是什么?

int *p[100];
Run Code Online (Sandbox Code Playgroud)

意思?这意味着*的表达*p[i]是类型的变量int提供的i是从一个整数值099.我们得到了一个变量,但是我们可以从指针或数组中得到它,所以我们必须弄清楚哪个.我们查阅运算符优先级表,发现索引运算符比解除引用运算符绑定"更严格".那是:

*p[i]
Run Code Online (Sandbox Code Playgroud)

是一样的

*(p[i])
Run Code Online (Sandbox Code Playgroud)

并记住,那东西是一个类型的变量int.对parens的内容进行解引用以生成类型的变量,int因此parens的内容必须是指针int.因此

p[i]
Run Code Online (Sandbox Code Playgroud)

是一个指向int的指针.怎么可能?这必须是一个指向类型指针的变量的获取!因此p[i]是指向int的类型指针的变量.由于这是一个索引操作,因此p必须是一个指针数组int.

现在你做下一个.

int (*p)[100];
Run Code Online (Sandbox Code Playgroud)

意味着什么?