#include<stdio.h>
#include<string.h>
int main()
{
char * p = "abc";
char * p1 = "abc";
printf("%d %d", p, p1);
}
当我打印两个指针的值时,它正在打印相同的地址。为什么?
#include<stdio.h>
#include<string.h>
int main()
{
char * p = "abc";
char * p1 = "abc";
printf("%d %d", p, p1);
}
当我打印两个指针的值时,它正在打印相同的地址。为什么?
p
和的地址p1
,那么您会注意到这两个指针存储在两个不同的地址下。在这种情况下,它们的值相同是不重要的。
p == p1
(它们没有不同),但是&p != &p1
(它们确实有所不同)。
Answers:
具有相同内容的两个不同字符串文字是放置在相同的存储位置还是不同的存储位置取决于实现。
您应该始终将p
和p1
当作两个不同的指针(即使它们具有相同的内容),因为它们可能指向或不指向同一地址。您不应该依赖编译器优化。
C11标准,6.4.5,字符串文字,语义
如果它们的元素具有适当的值,则不确定这些数组是否不同。如果程序尝试修改这样的数组,则行为是不确定的。
打印格式必须为%p
:
printf("%p %p", (void*)p, (void*)p1);
为何要查看此答案。
i modify one of the pointer, will the data in the other pointed also be modified
您可以修改指针,但不能修改字符串文字。例如,char *p="abc"; p="xyz";
可以很好地char *p="abc"; p[0]='x';
调用未定义的行为。这与无关volatile
。无论您是否使用volatile
,都不应更改我们在此感兴趣的任何行为。volatile
基本上是强制每次从内存中读取数据。
p
指向字符串文字"abc"
并p[0]='x'
尝试修改字符串文字的第一个字符。试图修改字符串文字是在C.未定义的行为
char []
在C中。因此,使其成为只读类型(const char*
在C ++中就是这种情况)也需要更改类型。[续]
"Strings are no longer modifiable, and so may be placed in read-only memory"
历史证明字符串文字曾经是可修改的;-)
==
您应该使用strcmpy()
函数来比较两个字符串(甚至是指针)。因为其他的编译器可能没有使用优化(取决于编译器-实施的延迟),如Alk回答PS:Blue Moon刚刚添加了优化。
您的编译器已完成称为“字符串池”的操作。您指定了两个指针,它们都指向同一个字符串文字-因此,它仅制作了文字的一个副本。
从技术上讲:它应该抱怨您没有将指针设为“ const”
const char* p = "abc";
这可能是因为您使用的是Visual Studio或不使用-Wall的GCC。
如果您明确希望它们在内存中存储两次,请尝试:
char s1[] = "abc";
char s2[] = "abc";
在这里,您明确声明需要两个c字符串字符数组,而不是两个指向字符的指针。
注意:字符串池是编译器/优化器功能,而不是语言的一个方面。这样,在不同环境下的不同编译器将根据优化级别,编译器标志以及字符串是否在不同的编译单元中而产生不同的行为。
gcc (Debian 4.4.5-8) 4.4.5
尽管使用,但不会抱怨(警告)-Wall -Wextra -pedantic
。
const
字符串文字。该警告由option启用-Wwrite-strings
。显然没有其他任何选项(例如-Wall
,-Wextra
或-pedantic
)启用该功能。
这实际上取决于您使用的是哪个编译器。
在我使用TC ++ 3.5的系统中,它为两个指针输出两个不同的值,即两个不同的地址。
您的编译器设计为st,它将检查内存中是否存在任何值,并且如果引用了相同的值,则根据其是否存在将重新分配或使用与先前存储的值相同的引用。
因此,不要过多地考虑它,因为它取决于编译器解析代码的方式。
它是编译器优化,但忘记了可移植性的优化。有时,编译后的代码比实际代码更具可读性。