[英]Difference between char * and char (*)[25]
#include<stdio.h>
int main()
{
char str[25] = "Hello World";
printf("%s\n", &str+2);
printf("%p\n",&str);
printf("%p\n",&str+2);
return 0;
}
The program above flashes an error for line 6 saying: 上面的程序在第6行闪烁了一个错误,说:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[25]’ [-Wformat=]
I wonder what's the difference between these two. 我想知道两者之间有什么区别。 And the output always shows two addresses having a difference of 32 bytes. 并且输出始终显示两个地址,它们之间的差值为32字节。 I was expecting an output with a difference of 2 as I'm trying to print the address of str
and address of str
+2. 当我尝试打印str
地址和str
+2的地址时,我期望输出的差异为2。 Can you explain? 你可以解释吗?
The difference for this two cases is quite simple. 这两种情况的区别非常简单。 Assume that we have an array of 25 characters: char arr[25];
假设我们有一个由25个字符组成的数组: char arr[25];
. 。 By convention expression arr
evaluated to a pointer to first array element, ie arr
is the same as &arr[0]
. 按照惯例,表达式arr
计算指向第一个数组元素的指针,即arr
与&arr[0]
。 Note, that here unary operator &
is applied to lvalue arr[0]
which has type of char
. 注意,这里一元运算符&
应用于具有char
类型的左值arr[0]
。 And as result &
gives an expression with type char *
(ie pointer to char
) 结果&
给出了一个char *
类型的表达式(即char
指针)
When we say &arr
- the lvalue is arr
, that is char [25]
(ie array of 25 characters). 当我们说&arr
左值是arr
时,即为char [25]
(即25个字符的数组)。 And as result the whole expression has type char (*)[25]
(ie pointer to array of 25 characters). 结果,整个表达式的类型为char (*)[25]
(即,指向25个字符的数组的指针)。 So, we've got expression with completely another type, that is not compatible with char *
. 因此,我们得到的表达式完全是另一种类型,与char *
不兼容。
Few notes about indexing. 关于索引的一些注释。 Difference between &arr + 2
and &arr
is 50 bytes (0x32 in hexadecimal), because sizeof(arr) == 25
. &arr + 2
和&arr
之间的差为50个字节(十六进制为0x32),因为sizeof(arr) == 25
。
char *
is a pointer to char
while char (*)[25]
is a pointer to an array of 25 char
's so these types are different and the compiler rightfully issues a warning. char *
是指向char
的指针,而char (*)[25]
是指向25个char
的数组的指针,因此这些类型不同,并且编译器正确地发出警告。
Moreover, since &str
is the address of the str
array and is of type char (*)[25]
, the value of &str+2
will be equal to: 此外,由于&str
是str
数组的地址并且类型为char (*)[25]
,所以&str+2
的值将等于:
&str + 2*sizeof(char (*)[25]) = &str + 2*25 = &str + 50 = &str + 0x32
Since a pointer is incremented according to the type it points to. 由于指针根据其指向的类型递增。
EDIT: after OP added a new line 6. 编辑:OP添加了新行6。
This is the correct syntax to print a string and pointer values. 这是打印字符串和指针值的正确语法。 In all cases there was a &
where it should not be, because a reference to the array identifier decays it to a pointer. 在所有情况下,在&
处都不应出现&
,因为对数组标识符的引用会将其衰减为指针。
#include <stdio.h>
int main()
{
char str[25] = "Hello World";
printf("%s\n", str+2);
printf("%p\n", (void*)str);
printf("%p\n", (void*)(str+2));
return 0;
}
Program output: 程序输出:
llo World
0018FF20
0018FF22
EDIT 2: This shows the effect of passing the pointer of the array. 编辑2:这显示了传递数组的指针的效果。 The compiler thinks you are addressing the third element of an array of strings each size 25. I have contrived to show how this undefined behaviour actually manifested. 编译器认为您正在处理每个大小为25的字符串数组的第三个元素。我试图说明这种未定义的行为是如何实际体现的。
#include <stdio.h>
int main()
{
char str[25] = "Hello World";
char abc[] = "abcdefghijklmnopqrstuvwxyz";
printf("%s\n", &str+2);
return 0;
}
Program output: 程序输出:
wxyz
After a little research I came up with this explanation. 经过一番研究,我得出了这个解释。 &str+2
is treated as a pointer to an array. &str+2
被视为指向数组的指针。 char (*)[25]
says that it's a pointer to a character array of size 25. To find the explain to why the output shows 32 byte difference I ran the program again and notices the output was displayed in hex ie char (*)[25]
说这是一个指向大小为25的字符数组的指针。要找到导致输出显示32字节差的原因的解释,我再次运行程序,注意到输出以十六进制显示,即
0x7ffd865b2710
0x7ffd865b2742
When converted to base 10, it becomes a difference of 50 bytes which is a pointer to the array that lies at second place to the current array(remember &str+2). 当转换为基数10时,它变为50字节的差,这是指向位于当前数组第二位的数组的指针(记住&str + 2)。 TO make it more clear here's a little memory diagram. 为了更加清楚,这是一个小内存图。
&str -----> current array ie str. array is 25 bytes long.
&str+1 -----> array lies after 1 position to current array. This address is 25 bytes away from &str.
&str+2-----> array lies after 2 position to current array. This address is 50 bytes away from &str.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.