char * s 和char(* s)之间有什么区别?
当我阅读有关C语言的书籍时,两级指针给我带来了很多困扰。
char s[5][5]; char *s[5]; char (*s)[5];
那么他们之间有什么区别?
在C中,最好说出声明。 然后,它变得直观。 为此,您遵循左右惯例。 这是怎么回事:
char *s[5];
你怎么说呢? 为此,您从变量名称s
的右侧开始,然后转到左侧。 所以你先说“s是a / an”,在右边,你看到一个[]
然后你说“s是一个数组……”。 然后你去左边看*
,并说“s是一个指针数组。” 这就是它。 它是一个5个指针的数组。 您可以在此数组中存储不同的指针。
现在换另一个:
char (*s)[5];
你以同样的方式开始。 “s是a / an”,然后看看()
。 ()
中的任何东西都比外面的东西更接近。 所以*
与s
比[]
更紧密地绑定。 所以你现在说,“s是一个指针……”现在你走出括号并看到[]
。 所以你继续说,“s是一个指向数组的指针”。 而这正是它的本质。 它是一个指针,指向数组的第一个元素。
现在遵循相同的逻辑,并尝试猜测以下内容:
int (*callme)(int a, int b) int (*callme[10])(int a, int b)
提示,最后一个可用于为函数创建查找表。
编辑:
正如评论中所提到的,一开始也有一个char
。 我从来没有能够找到一种简单的方式来说明这一点,但从上下文中可以清楚地看出来。 例如,在第一个示例中, char
定义数组的类型,而在第二个示例中,它定义指针。 在我发布的练习中, int
定义了函数返回值的类型。 通常使用这些定义,将只有一个具有未定义类型的项。 这就是我如何找出类型的去向。
- 首先是二维char数组
- 第二个是指向char的指针数组
- 第三个是指向char数组的指针
虽然涵盖了声明 ,但也可能指出使用上的差异:
char s[5][5];
–
-
s
指向已分配内存的区域(如果是全局堆,则为本地堆栈), - 你可以在
s[0][0]
..s[4][4]
(或s[0]
..s[24]
)安全地写出最多25个char值, -
sizeof(s)
== 25。
char *s[5];
–
-
s
指向已分配内存的区域(如果是全局堆,则为本地堆栈), - 你可以在
s[0]
..s[4]
安全地写出最多5个指针值, -
sizeof(s)
== 40(*)。
char (*s)[5];
–
-
s
没有指向任何已分配的内存 – 此时它只是一个未初始化的指针, - 你可以安全地在
&s
写一个指针值, -
sizeof(s)
== 8(*)。
(*)注意:假设是64位架构。
1.char s [5] [5];
这里是具有5行和5列的二维数组。 在这5行和5列中,您将保存字符类型的元素。
2.char * s [5]; s是具有5个元素的一维数组,每个元素是指向字符的类型的指针。
3.char(* s)[5]; s是这里的指针而不是数组。 S指向一个字符数组。 例如。
char arr[5][5]; char(*s)[5]; s = arr;
s [0] [0]将与arr [0] [0]的数组相同