C 字符指针赋值矩之间的差异

C 字符指针赋值矩之间的差异,c,c-strings,C,C Strings,今天有人告诉我,这个代码: int main(){ char *a; a = "foobar"; /* a used later to strcpy */ return 0; } 是不好的,可能会导致问题和错误。 然而,我的代码没有任何问题,我不明白,这和 int main(){ char *a = "foobar"; /* a used later to strcpy */ return 0; } 我认为这是“正确的”方法。 有人能描述一下,为什么这两种代码是不同的吗? 如果

今天有人告诉我,这个代码:

int main(){
 char *a;
 a = "foobar";
 /* a used later to strcpy */
 return 0;
}
是不好的,可能会导致问题和错误。 然而,我的代码没有任何问题,我不明白,这和

int main(){
 char *a = "foobar";
 /* a used later to strcpy */
 return 0;
}
我认为这是“正确的”方法。 有人能描述一下,为什么这两种代码是不同的吗?
如果第一个可能有问题,请举例说明

在功能上,它们是相同的

在前一个代码段中,
a
被分配给字符串文本;在后者中,
a
用字符串文本初始化。 在这两种情况下,
a
指向字符串文字(不能修改)


没有理由认为一个比另一个更正确。我更喜欢后者,但那只是我个人的喜好。

从功能上讲,它们是一样的

在前一个代码段中,
a
被分配给字符串文本;在后者中,
a
用字符串文本初始化。 在这两种情况下,
a
指向字符串文字(不能修改)


没有理由认为一个比另一个更正确。我更喜欢后者,但这只是我个人的偏好。

两个代码段都同样糟糕,因为它们都以指向常量数据的非常量指针结尾。如果使用非常量指针(尝试)更改数据,您将获得未定义的行为:从它工作到程序崩溃,一切都可能发生,包括忽略修改指令

正确的方法是使用常量指针或初始化非常量数组

const char *a = "foobar";

但请注意,在后一种情况下,您有一个真正的数组而不是指针,因此如果您确实需要指针语义,也可以这样做:

char _a[] = "foobar";
char *a = _a;

这两个代码段都同样糟糕,因为它们都以指向常量数据的非常量指针结尾。如果使用非常量指针(尝试)更改数据,您将获得未定义的行为:从它工作到程序崩溃,一切都可能发生,包括忽略修改指令

正确的方法是使用常量指针或初始化非常量数组

const char *a = "foobar";

但请注意,在后一种情况下,您有一个真正的数组而不是指针,因此如果您确实需要指针语义,也可以这样做:

char _a[] = "foobar";
char *a = _a;

有些地方有编码标准,例如通过Coverity等工具帮助进行静态代码分析

我在几个地方看到的一个编码实践规则是,变量应该总是被声明为初始化的,以简化事情,使分析更容易

第二个代码段比第一个代码段更接近该规则,因为不可能在未初始化的情况下插入新代码


在代码维护方面,这是一个积极的好处。

有些地方有编码标准,例如通过Coverity等工具帮助进行静态代码分析

我在几个地方看到的一个编码实践规则是,变量应该总是被声明为初始化的,以简化事情,使分析更容易

第二个代码段比第一个代码段更接近该规则,因为不可能在未初始化的情况下插入新代码


对于代码维护来说,这是一个积极的好处。

为什么您认为第一个比第二个更糟糕?它们同样糟糕,因为指针不是常量。
strcpy()
中的
a
是如何使用的?当然不是作为目标;)我没有使用const,因为我用的是比ansic更早的C语言编写代码,还没有
const
关键字。为什么你认为第一个比第二个更糟糕?它们同样糟糕,因为指针不是常量。
strcpy()
中的
a
是如何使用的?当然不是作为目标;)我没有使用const,因为我是用C编写代码的,比ANSI C早,还没有
const
关键字。我没有使用
const
关键字,因为我用C编写了这段代码,const出现在C89中,在大学里他们教我们更旧的标准,我只是从那里复制了我的代码。@Kaznov我的回答确实假设了一个相当新的C版本:-)。我已经足够大了,记得原来的K&R C。。。在那些旧版本中,stringliteral是可修改的,您的代码是正确的。但是,如果你必须生成真实的代码,你就必须迅速改变这些编码实践……我没有使用
const
关键字,因为我用普通的C编写了这段代码,const出现在C89中,在大学里,他们教给我们更旧的标准,我只是从那里复制了我的代码。@Kaznov我的答案确实假设了一个相当新的C版本:-)。我已经足够大了,记得原来的K&R C。。。在那些旧版本中,stringliteral是可修改的,您的代码是正确的。但是,如果您必须生成真实的代码,那么您必须快速更改这些编码实践。。。