简体   繁体   English

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

[英]What's the difference between the types - int * and int *[100] in C?

Kinda of a noob so don't kill me here. 有点像菜鸟所以不要在这里杀了我。

What's the difference between the following codes? 以下代码之间有什么区别?

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. 
  1. This is a pointer to an int : 这是一个指向int指针

     int *p; 
     ┌────┐ │int*│ └────┘ 

    It should point at an int , something like this: 它应该指向一个int ,类似这样:

     ┌────┐ │int*│ └─┃──┘ ▼ ┌───┐ │int│ └───┘ 
  2. This is an array of 100 pointers to int : 这是一个包含100个int指针数组

     int *p[100]; 

    That is, it gives you 100 pointers. 也就是说,它会给你100个指针。

     ┌────┬────┬────┬────┬────┬────┬┄ │int*│int*│int*│int*│int*│int*│ └────┴────┴────┴────┴────┴────┴┄ 

    Each pointer should point an int , perhaps like this: 每个指针都应该指向一个int ,也许是这样的:

     ┌────┬────┬────┬────┬────┬────┬┄ │int*│int*│int*│int*│int*│int*│ └─┃──┴─┃──┴─┃──┴─┃──┴─┃──┴─┃──┴┄ ▼ ▼ ▼ ▼ ▼ ▼ ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌┄ │int││int││int││int││int││int││ └───┘└───┘└───┘└───┘└───┘└───┘└┄ 

    Of course, there's no reason they can't all point at the same int , or whatever. 当然,没有理由他们不能都指向同一个int ,或者其他什么。

    You may want to use an array of pointers if you want many pointers that you can easily iterate over. 如果你想要很多可以轻松迭代的指针,你可能想要使用一个指针数组。 You may, for example, dynamically allocate objects and have each pointer point at a different object: 例如,您可以动态分配对象并使每个指针指向不同的对象:

     p[0] = new int(0); p[1] = new int(0); // ... 

    Perhaps dynamically allocating int s isn't the best example, but I think the point is clear. 也许动态分配int不是最好的例子,但我认为这一点很清楚。

  3. This is a pointer to an array of 100 int : 这是一个指向100 int数组的指针

     int (*p)[100]; 

    That is, it gives you just 1 pointer: 也就是说,它只给你一个指针:

     ┌───────────┐ │int(*)[100]│ └───────────┘ 

    It should point at an array that contains 100 int s: 它应该指向一个包含100个int的数组:

     ┌───────────┐ │int(*)[100]│ └─┃─────────┘ ▼ ┌───┬───┬───┬───┬───┬───┬┄ │int│int│int│int│int│int│ └───┴───┴───┴───┴───┴───┴┄ 

    You will get a pointer to an array when you use the address-of operator ( & ) on the name of an array. 当您在数组名称上使用address-of运算符( & )时,您将获得指向数组的指针。 For example: 例如:

     int arr[100] = { /* some initial values */ }; int (*p)[100] = &arr; 

    Here, I've taken the address of the arr array, which gives me a pointer to that array. 在这里,我采用了arr数组的地址,它给了我一个指向该数组的指针。 If you then want to access an element of the array, you have to dereference the pointer first: (*p)[3] will access element 3. 如果您想要访问数组的元素,则必须首先取消引用指针: (*p)[3]将访问元素3。


Side note: 边注:

Always remember that arrays are not pointers . 永远记住, 数组不是指针 As we have just seen, we can take the address of an array to get a pointer to it, just like any other (non-temporary) object in C++. 正如我们刚才看到的,我们可以获取数组的地址来获取指向它的指针,就像C ++中的任何其他(非临时)对象一样。 The only special connection between arrays and pointers is that the name of an array can be implicitly converted to a pointer to the array's first element. 数组和指针之间唯一的特殊连接是数组的名称可以隐式转换为指向数组第一个元素的指针。 That means the following is valid: 这意味着以下内容有效:

int arr[100] = { /* some initial values */ };
int* p = arr;

The pointer p will point at the first element in arr . 指针p将指向arr中的第一个元素。 Note that p is not a pointer to the array, but a pointer to an element of the array. 请注意, p 不是指向数组的指针,而是指向数组元素的指针。

(Also note that there is no such thing as an array type function argument. If you write something like int p[] as a function argument, it is transformed by the compiler to be a int* .) (另请注意,没有数组类型函数参数。如果你编写类似int p[]的函数作为函数参数,它会被编译器转换为int* 。)

Sounds like you could use an introduction to the Spiral Rule . 听起来你可以使用螺旋规则的介绍。

Start at the variable and "spiral" your way around right to left: 从变量开始,从左到右依次“螺旋”:

              +-------+
              | +--+  |             // So we have:
              | |  |  |                    p    // p     
          int * p  |  |                  * p    // p is a pointer
           ^  ^    |  |              int * p    // p is a pointer to an int
           |  +----+  |
           +----------+

Next one: 下一个:

              +--------+
              | +--+   |         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
           |  +----+   |
           +-----------+

Finally, a new part of the rule, do anything in parenthesis first: 最后,规则的一部分,首先在括号中做任何事情:

                   +-----+            
                   | +-+ |    
                   | ^ | |         ( 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
               +---------+    

If you're online/have access to a computer, it's always usefule to use the cdecl.org site, but it's important to be able to read code offline as well, and this rule will let you do just that. 如果你在线/可以访问计算机,那么使用cdecl.org网站总是很有用,但是能够离线阅读代码也很重要,而这条规则可以让你做到这一点。

Kinda of a noob so don't kill me here 有点像菜鸟所以不要在这里杀了我

Working out what a type means in C can be tricky even for experts. 即使对于专家来说,解决C中的类型意味着什么也很棘手。 No worries. 别担心。

What's the difference between the following codes? 以下代码之间有什么区别?

The other answers are good and I have no intention of contradicting them. 其他答案都很好,我无意反驳。 Rather, here's yet another way to think about it. 相反,这是考虑它的另一种方式。 We need to define three things: 我们需要定义三件事:

  • A variable is a thing that supports three operations. 变量是支持三个操作的东西。 The fetch operation takes a variable and produces its current value. 获取操作接受一个变量并产生其当前值。 The fetch operation has no notation; 获取操作没有表示法; you simply use the variable. 你只需使用变量。 The store operation takes a variable and a value, and stores the value in the variable. 存储操作采用变量和值,并将值存储在变量中。 The address operation takes a variable and produces a pointer . 地址操作接受一个变量并产生一个指针

  • A pointer is a thing that supports one operation. 指针是支持一个操作的东西。 The dereference operation, written as prefix *pointer , takes a pointer and produces a variable. 作为前缀*pointer编写的解除引用操作接受指针并生成变量。 (Pointers support other operations such as arithmetic and indexing -- which is a form of arithmetic -- but let's not go there.) (指针支持其他操作,如算术和索引 - 这是算术的一种形式 - 但是不要去那里。)

  • An array is a thing that supports one operation. 数组是支持一个操作的东西。 The index operation takes an array and an integer and produces a variable . 索引操作采用数组和整数并生成变量 It's syntax is postfix: array[index] 它的语法是postfix: array[index]

OK, so now we come to your question. 好的,现在我们来回答您的问题。 What does the declaration 宣言是什么?

int p;

mean? 意思? That the expression p is a variable of type int . 表达式pint类型的变量 Note that this is a variable; 请注意,这是一个变量; you can store things to p . 你可以把东西存放到p What does the declaration 宣言是什么?

int *p;

mean? 意思? That the expression *p is a variable of type int . 表达式*pint类型的变量。 Now that we know that we can deduce what p is. 现在我们知道我们可以推断出什么是p Since *p is a dereference and produces a variable, p must be a pointer to int. 由于*p是取消引用并生成变量,因此p必须是指向int的指针。 What does the declaration 宣言是什么?

int *p[100];

mean? 意思? It means that *the expression *p[i] is a variable of type int provided that i is an integer value from 0 to 99 . 这意味着*表达式*p[i]int类型的变量,前提是i099的整数值。 We got a variable out, but we could have gotten there from either the pointer or the array, so we have to figure out which. 我们得到了一个变量,但是我们可以从指针或数组中得到它,所以我们必须弄清楚哪个。 We consult the operator precedence table and discover that the indexing operator binds "tighter" than the dereferencing operator. 我们查阅运算符优先级表,发现索引运算符比解除引用运算符绑定“更严格”。 That is: 那是:

*p[i]

is the same thing as 是一样的

*(p[i])

and remember, that thing is a variable of type int . 并记住,那个东西是int类型的变量。 The contents of the parens are dereferenced to produce a variable of type int so the contents of the parens must be a pointer to int . 对parens的内容进行解引用以生成int类型的变量,因此parens的内容必须是指向int指针 Therefore 因此

p[i]

is a pointer to int. 是一个指向int的指针。 How is that possible? 怎么可能? This must be a fetch of a variable of type pointer-to-int! 这必须是一个指向类型指针的变量的获取! So p[i] is a variable of type pointer to int. 所以p[i]是指向int的类型指针的变量。 Since this is an index operation, p must be an array of pointers to int . 由于这是一个索引操作,因此p必须是指向int的指针数组。

Now you do the next one. 现在你做下一个。

int (*p)[100];

means what? 意味着什么?

int *p; --> Declares a pointer to an integer type. - >声明一个指向整数类型的指针。
int *p[100]; -->Declares an array of 100 pointers to integer type. - >声明一个包含整数类型的100个指针的数组。
int (*p)[100]; --> Declares a pointer to an array of 100 integers. - >声明一个指向100个整数数组的指针。

Use cdecl for translating such types. 使用cdecl来翻译这些类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM