c指针指向的数组的打印地址
在下面的代码中,str
是一个指针,用于存储数组Goodbye
的地址。阵列Goodbye
的地址从4196004
开始,并且指针*str2
的值是-1226226648
。我的问题是,有没有办法使用指针*str2
来打印数组Goodbye
的地址?c指针指向的数组的打印地址
我想,解引用str2
此行printf("%d %d %s\n", *str2, str2, str2);
和它打印71
这是ASCII码为H
,但我怎么会打印地址4196004
int main(int argc, char **argv) {
char str1[] = "Hello";
char *str2 = "Goodbye";
printf("%d %d %s\n", &str1, str1, str1);
printf("%p %d %s\n", &str2, str2, str2);
}
Output:
-1226226640 -1226226640 Hello
-1226226648 4196004 Goodbye
你的代码调用未定义行为,因为您尝试打印地址,而不使用%p
printf()
提到:
p
指针地址
,不投给void
,你应该。
所以,像这样做,而不是:
printf("%p %p %s\n", (void*)&str1, (void*)str1, str1);
printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);
可能的输出:
0x7ffddaf7e67a 0x7ffddaf7e67a Hello
0x7ffddaf7e670 0x4005c4 Goodbye
关于str2
我们可以区分“地址到指针str2
点”,这是地址,其中字符串文字Goodbye
将从“存储指针str2
的地址”(其为变量的地址(例如0x7fff5fbff710
))驻留(例如0x10007bf04
)其中存储地址值0x10007bf04
。
int main(int argc, char **argv) {
char str1[] = "Hello";
char *str2 = "Goodbye";
printf("%p %p %s\n", (void*)&str1[0], (void*)str1, str1);
printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);
}
相反的指针,*str2
表示,因为它取消引用指针str2
字符值。获取“str2的地址”将成为str2
指向的字符串文字的第一个字符的地址。您可以将其编写为&(*str2)
或&str2[0]
,但都转换为str2
。
请注意,使用格式"%d"
打印指针会调用未定义的行为。
开始通过固定未定义行为 - 投你的指针void*
,并使用%p
打印它们:
printf("%p %p %s\n", (void*)&str1, (void*)str1, str1);
printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);
这produces the following output:
0x7ffe95676bf0 0x7ffe95676bf0 Hello
0x7ffe95676be8 0x2b4dca5eb7d4 Goodbye
让我们通过它来看看为什么有str1
和str2
的打印行之间的差异。
原因是str1
是一个数组,而str2
是一个指针。当你用一个运算符&
指向一个数组时,你产生一个指向数组最初元素的指针;当您将数组隐式转换为指针时,您还会获得指向数组最初元素的指针。因此,对于&str1
和str1
,%p
的两个打印输出产生相同的值0x7ffe95676bf0
。
另一方面,str2
是一个指针。它指向一些东西(字符串文字"Goodbye"
),但它也有自己的地址。当您打印str2
而没有&
时,您将获得指针的值,即字符串字面值"Goodbye"
的位置。然而,当您打印&str2
时,会得到指针str2
的指针,这是str2
的位置。这与"Goodbye"
的位置不同,因此打印输出是不同的。
如果你开始的str2
地址,即
char *str2 = "Goodbye";
char **ptrStr2 = &str2;
您可以通过提领得到"Goodbye"
位置,即
printf("%p %s\n", (void*)*ptrStr2, *ptrStr2);
非常感谢您的有用答复。我能再问一个问题吗?如果你使用'%p',它是否需要转换为'void *'?如果是的话 - 为什么这是必要的? –
@articsol是的,除char和unsigned char指针之外的所有指针都是必需的,它们保证与void指针具有相同的表示形式。 %p假定你传递了一个void指针,所以你需要添加一个转换以确保传递正确的表示。 – dasblinkenlight
非常感谢 –
对于初学者来说,你应该使用正确的函数printf
中的转换说明符。否则,函数的行为是未定义的。
所以因为使用了转换说明%d
与指针这些调用
printf("%d %d %s\n", &str1, str1, str1);
printf("%p %d %s\n", &str2, str2, str2);
是错误的。
我的问题是,有没有办法打印地址阵列再见使用 指针* str2?
实际上,对应于字符串字面值"Goodbye"
的数组地址与字符串文字的第一个字符的地址相同。
char *str2 = "Goodbye";
但是,您无法使用指针str2
获取指向字符串文字的指针。
什么问题?
指针str2
对它是否指向char
类型的单个对象或某些数组的第一个字符一无所知。它不保留这样的信息。
考虑到对应于字符串字面值"Goodbye"
的数组的类型为char[8]
。所以指向数组的指针应该有char (*)[8]
类型。
你可以写例如
char (*str2)[8] = &"Goodbye";
在这种情况下,指针str2
确实将有数组的地址。以其他方式,因为它是你的榜样
char *str2 = "Goodbye";
定义因为有人提到指针一无所知阵列,其大小不能获取数组的地址指针。
另一方面,字符串文字的第一个字符的地址值等于指向字符串文字的指针的值。也就是说,如果首先要考虑的声明
char str1[] = "Hello";
则表达式str1
和&str1
会产生相同的值虽然表现有不同的类型。第一个类型为char *
(如果在数组指示符被隐式转换为指向其第一个元素的指针时在上下文中使用该表达式)。第二种是char (*)[6]
。但是,这两个值是相等的。:)
它是从输出似乎(前提是你使用正确的转换说明)
-1226226640 -1226226640 Hello
你有不确定的行为。请参阅https://stackoverflow.com/q/5286451/4389800 – usr
@artic sol在您的代码片段中没有名称str。:) –