指向 char 类型数组的指针可以用来显示数组的内容而无需解引用运算符?
Pointer pointing to char type array can be used to show the content of the array without a dereference operator?
int main(int argc, char *argv[])
{
char b[]="Among Us";
char* string2 = &b[0];
printf("Print address of b\t\t= %p\n", &b[0]);
printf("Print content of string2\t= %p\n", string2);
printf("Print content of string2\t= %s\n", string2); // why ???
system("PAUSE");
return 0;
}
为什么最后的printf给我们显示的是b的内容?它不是应该向我们显示 b 的地址,而是以 %s 格式显示吗?
我认为printf("Print content of string2\t= %s\n", *string2);
是通过string2打印b内容的正确方法,但显然这是错误的方法。
printf("Print content of string2\t= %s\n", string2);
即使在 string2
之前没有引用运算符,也会打印整个字符串,因为 %s
,按照标准定义,需要一个 char *
,即地址。
Refer here
Why does the last printf show us the content of b?
数组中第一个元素的地址是数组本身的地址。 => 您也可以将 string2
用作 b
Variable names don't exist anymore after the compiler runs , program
care address of variable
参考这个:How are variable names stored in memory in C?
你最好重温你的 C 书的内存地址 & 指针 章节。
假设你是运行一个32位系统,它使用4字节寻址内存&内存状态您的代码是:
// char array "b"
address value
======= =====
aaaa:0001 A // hex value 41
aaaa:0002 m // hex value 6d
aaaa:0003 o // hex value 6f
aaaa:0004 n // hex value 6e
aaaa:0005 g
aaaa:0006 // that's a "space" char, hex value 20
aaaa:0007 U
aaaa:0008 s
aaaa:0009 0 // that's a zero, hex value 00
// pointer "string2"
// pointing to "aaaa:0001"
// in reverse order
// depending on endianness of your system
address value
======= =====
ffff:0001 01
ffff:0002 00
ffff:0003 aa
ffff:0004 aa
- 您的第一个
printf
将打印 aaaa:0001
为十六进制;即数组 b
. 的内存地址
- 你的第二个
printf
将打印 aaaa:0001
为十六进制;即存储在地址 ffff:0001
到 ffff:0004
中的值。从格式说明符 %p
,编译器将知道它将打印一个内存地址并读取 4 个字节并在打印前还原它们。
- 您的第三个
printf
将打印 Among Us
;从格式说明符 %s
中,编译器将知道它将打印一个字符数组并打印字符 它指向的地址 ,直到 printf
到达一个字符串终止符,它是 0
.
说明符 %p
和 %s
都需要一个指针。
%p
将打印指针的 value。
但是%s
会使用指针来打印一个C字符串,即由'[=15=]'
分隔的char
数组。
如果你给出*string2
,它不是指针。它是指针指向的对象的值,在您的例子中是 char
.
将编译器的警告级别提高到最大,希望它足够聪明,可以识别格式字符串并检查参数。
int main(int argc, char *argv[])
{
char b[]="Among Us";
char* string2 = &b[0];
printf("Print address of b\t\t= %p\n", &b[0]);
printf("Print content of string2\t= %p\n", string2);
printf("Print content of string2\t= %s\n", string2); // why ???
system("PAUSE");
return 0;
}
为什么最后的printf给我们显示的是b的内容?它不是应该向我们显示 b 的地址,而是以 %s 格式显示吗?
我认为printf("Print content of string2\t= %s\n", *string2);
是通过string2打印b内容的正确方法,但显然这是错误的方法。
printf("Print content of string2\t= %s\n", string2);
即使在 string2
之前没有引用运算符,也会打印整个字符串,因为 %s
,按照标准定义,需要一个 char *
,即地址。
Refer here
Why does the last printf show us the content of b?
数组中第一个元素的地址是数组本身的地址。 => 您也可以将 string2
用作 b
Variable names don't exist anymore after the compiler runs , program care address of variable
参考这个:How are variable names stored in memory in C?
你最好重温你的 C 书的内存地址 & 指针 章节。
假设你是运行一个32位系统,它使用4字节寻址内存&内存状态您的代码是:
// char array "b"
address value
======= =====
aaaa:0001 A // hex value 41
aaaa:0002 m // hex value 6d
aaaa:0003 o // hex value 6f
aaaa:0004 n // hex value 6e
aaaa:0005 g
aaaa:0006 // that's a "space" char, hex value 20
aaaa:0007 U
aaaa:0008 s
aaaa:0009 0 // that's a zero, hex value 00
// pointer "string2"
// pointing to "aaaa:0001"
// in reverse order
// depending on endianness of your system
address value
======= =====
ffff:0001 01
ffff:0002 00
ffff:0003 aa
ffff:0004 aa
- 您的第一个
printf
将打印aaaa:0001
为十六进制;即数组b
. 的内存地址
- 你的第二个
printf
将打印aaaa:0001
为十六进制;即存储在地址ffff:0001
到ffff:0004
中的值。从格式说明符%p
,编译器将知道它将打印一个内存地址并读取 4 个字节并在打印前还原它们。 - 您的第三个
printf
将打印Among Us
;从格式说明符%s
中,编译器将知道它将打印一个字符数组并打印字符 它指向的地址 ,直到printf
到达一个字符串终止符,它是0
.
说明符 %p
和 %s
都需要一个指针。
%p
将打印指针的 value。
但是%s
会使用指针来打印一个C字符串,即由'[=15=]'
分隔的char
数组。
如果你给出*string2
,它不是指针。它是指针指向的对象的值,在您的例子中是 char
.
将编译器的警告级别提高到最大,希望它足够聪明,可以识别格式字符串并检查参数。