[英]What's the difference between the types - int * and int *[100] in C?
有点像菜鸟所以不要在这里杀了我。
以下代码之间有什么区别?
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.
这是一个指向int
的指针 :
int *p;
┌────┐ │int*│ └────┘
它应该指向一个int
,类似这样:
┌────┐ │int*│ └─┃──┘ ▼ ┌───┐ │int│ └───┘
这是一个包含100个int
指针的数组 :
int *p[100];
也就是说,它会给你100个指针。
┌────┬────┬────┬────┬────┬────┬┄ │int*│int*│int*│int*│int*│int*│ └────┴────┴────┴────┴────┴────┴┄
每个指针都应该指向一个int
,也许是这样的:
┌────┬────┬────┬────┬────┬────┬┄ │int*│int*│int*│int*│int*│int*│ └─┃──┴─┃──┴─┃──┴─┃──┴─┃──┴─┃──┴┄ ▼ ▼ ▼ ▼ ▼ ▼ ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐┌┄ │int││int││int││int││int││int││ └───┘└───┘└───┘└───┘└───┘└───┘└┄
当然,没有理由他们不能都指向同一个int
,或者其他什么。
如果你想要很多可以轻松迭代的指针,你可能想要使用一个指针数组。 例如,您可以动态分配对象并使每个指针指向不同的对象:
p[0] = new int(0); p[1] = new int(0); // ...
也许动态分配int
不是最好的例子,但我认为这一点很清楚。
这是一个指向100 int
数组的指针 :
int (*p)[100];
也就是说,它只给你一个指针:
┌───────────┐ │int(*)[100]│ └───────────┘
它应该指向一个包含100个int
的数组:
┌───────────┐ │int(*)[100]│ └─┃─────────┘ ▼ ┌───┬───┬───┬───┬───┬───┬┄ │int│int│int│int│int│int│ └───┴───┴───┴───┴───┴───┴┄
当您在数组名称上使用address-of运算符( &
)时,您将获得指向数组的指针。 例如:
int arr[100] = { /* some initial values */ }; int (*p)[100] = &arr;
在这里,我采用了arr
数组的地址,它给了我一个指向该数组的指针。 如果您想要访问数组的元素,则必须首先取消引用指针: (*p)[3]
将访问元素3。
永远记住, 数组不是指针 。 正如我们刚才看到的,我们可以获取数组的地址来获取指向它的指针,就像C ++中的任何其他(非临时)对象一样。 数组和指针之间唯一的特殊连接是数组的名称可以隐式转换为指向数组第一个元素的指针。 这意味着以下内容有效:
int arr[100] = { /* some initial values */ };
int* p = arr;
指针p
将指向arr
中的第一个元素。 请注意, p
不是指向数组的指针,而是指向数组元素的指针。
(另请注意,没有数组类型函数参数。如果你编写类似int p[]
的函数作为函数参数,它会被编译器转换为int*
。)
听起来你可以使用螺旋规则的介绍。
从变量开始,从左到右依次“螺旋”:
+-------+
| +--+ | // So we have:
| | | | p // p
int * p | | * p // p is a pointer
^ ^ | | int * p // p is a pointer to an int
| +----+ |
+----------+
下一个:
+--------+
| +--+ | 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
| +----+ |
+-----------+
最后,规则的一部分,首先在括号中做任何事情:
+-----+
| +-+ |
| ^ | | ( 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
+---------+
如果你在线/可以访问计算机,那么使用cdecl.org网站总是很有用,但是能够离线阅读代码也很重要,而这条规则可以让你做到这一点。
有点像菜鸟所以不要在这里杀了我
即使对于专家来说,解决C中的类型意味着什么也很棘手。 别担心。
以下代码之间有什么区别?
其他答案都很好,我无意反驳。 相反,这是考虑它的另一种方式。 我们需要定义三件事:
变量是支持三个操作的东西。 获取操作接受一个变量并产生其当前值。 获取操作没有表示法; 你只需使用变量。 存储操作采用变量和值,并将值存储在变量中。 地址操作接受一个变量并产生一个指针 。
指针是支持一个操作的东西。 作为前缀*pointer
编写的解除引用操作接受指针并生成变量。 (指针支持其他操作,如算术和索引 - 这是算术的一种形式 - 但是不要去那里。)
数组是支持一个操作的东西。 索引操作采用数组和整数并生成变量 。 它的语法是postfix: array[index]
好的,现在我们来回答您的问题。 宣言是什么?
int p;
意思? 表达式p
是int
类型的变量 。 请注意,这是一个变量; 你可以把东西存放到p
。 宣言是什么?
int *p;
意思? 表达式*p
是int
类型的变量。 现在我们知道我们可以推断出什么是p
。 由于*p
是取消引用并生成变量,因此p
必须是指向int的指针。 宣言是什么?
int *p[100];
意思? 这意味着*表达式*p[i]
是int
类型的变量,前提是i
是0
到99
的整数值。 我们得到了一个变量,但是我们可以从指针或数组中得到它,所以我们必须弄清楚哪个。 我们查阅运算符优先级表,发现索引运算符比解除引用运算符绑定“更严格”。 那是:
*p[i]
是一样的
*(p[i])
并记住,那个东西是int
类型的变量。 对parens的内容进行解引用以生成int
类型的变量,因此parens的内容必须是指向int
的指针 。 因此
p[i]
是一个指向int的指针。 怎么可能? 这必须是一个指向类型指针的变量的获取! 所以p[i]
是指向int的类型指针的变量。 由于这是一个索引操作,因此p
必须是指向int
的指针数组。
现在你做下一个。
int (*p)[100];
意味着什么?
int *p;
- >声明一个指向整数类型的指针。
int *p[100];
- >声明一个包含整数类型的100个指针的数组。
int (*p)[100];
- >声明一个指向100个整数数组的指针。
使用cdecl来翻译这些类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.