这个问题可以作为所有常见问题的参考:
当我将数据复制/扫描到未初始化指针所指向的地址时,为什么会出现神秘崩溃或"分段错误"?
例如:
char* ptr;
strcpy(ptr, "hello world"); // crash here!
Run Code Online (Sandbox Code Playgroud)
要么
char* ptr;
scanf("%s", ptr); // crash here!
Run Code Online (Sandbox Code Playgroud) 当大小相同时,float和integer数据类型之间有什么区别?
我需要编写表单的声明
a = a || expr;
Run Code Online (Sandbox Code Playgroud)
expr应该在哪里评估,并将结果分配给aiff a未设置.这取决于逻辑OR的短路能力.
当然,写上述内容的时间更短
a ||= expr;
Run Code Online (Sandbox Code Playgroud)
但是(令我惊讶的是)C没有逻辑赋值运算符.
所以我的问题是双重的.首先,是否有一种更短的方式来编写标准C中的第一个语句(三元运算符更糟糕 - a = a ? a : expr需要我拼出a三次).
其次,为什么C中没有逻辑分配?我能想到的可能原因是:
编辑
请解锁这个问题因为:
与之相关的问题(作为所谓的副本)尚未得到回答.该问题的(已接受)答案表明,||=由于重复了该功能,因此不存在|=.这是错误的答案.|=不会短路.
C和C++不是同一种语言.我想知道为什么C没有它.实际上,像C++这样的派生语言,特别是Java(没有像Edmund的答案中提到的遗留代码问题那样)的问题使得这个问题更加有趣.
编辑2
现在看起来我原来的意图是错的.在语句中a = a || expr(其中a是积分并expr返回一个整数值,首先两者a并将expr隐式转换为"布尔值",然后将"布尔"值赋值给a.这将是不正确的 - 积分值将丢失.谢谢,詹斯和埃德蒙.
所以对于问题的第一部分,编码我的意图的正确方法,而不是替代方法:)将是:
if (!a) a = expr;
Run Code Online (Sandbox Code Playgroud)
要么
a = a ? a : expr;
Run Code Online (Sandbox Code Playgroud)
他们应该优化相同(我认为)虽然我个人更喜欢第一个(因为它有一个较少a的类型). …
我正在寻找在抽象基类中定义的测试方法的方法/最佳实践.我可以直接想到的一件事是在基类的所有具体子类上执行测试,但这在某些时候似乎过多.
考虑这个例子:
import abc
class Abstract(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def id(self):
return
@abc.abstractmethod
def foo(self):
print "foo"
def bar(self):
print "bar"
Run Code Online (Sandbox Code Playgroud)
是否可以在bar不进行任何子类化的情况下进行测试?
我去了一个采访中,我被问到这个问题:
您对以下内容有何看法?
Run Code Online (Sandbox Code Playgroud)int i; scanf ("%d", i); printf ("i: %d\n", i);
我回答了:
我做出的回应是错误的.我不堪重负.
在那之后他们解雇了我:
在某些情况下,程序会崩溃并导致核心转储.
我不明白为什么程序会崩溃?谁有人解释我的原因?任何帮助赞赏.
gcc -std=c23最新的 gcc 13.x (trunk) 给出了此代码的编译器错误 ( ):
int* p = false;\nRun Code Online (Sandbox Code Playgroud)\n\n\n错误:
\nint *使用类型“ ”初始化类型“_Bool”时出现类型不兼容
这怎么可能是正确的呢?
\nC23 6.2.5 \xc2\xa78-9(类型 - 整数类型的定义):
\n\n\n\n
bool与标准有符号整数类型相对应的类型和无符号整数类型是标准无符号整数类型。标准有符号整数类型和标准无符号整数类型统称为标准整数类型;
\n
C23 6.6 \xc2\xa78 (常量表达式 - 整型常量表达式的定义):
\n\n\n整数常量表达式应具有整数类型...
\n
C23 6.3.2.3(指针-空指针常量的定义)
\n\n\n值为 0 的整型常量表达式,此类表达式转换为 类型
\nvoid *,或预定义常量nullptr称为空指针常量
C23 6.5.16.1(简单分配):
\n\n约束
\n/--/ …
一个简单的程序:
int main()
{
long i = i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译为C不会出现错误,也不会出现警告.
$ gcc -Wall -Wextra -pedantic 1.c
Run Code Online (Sandbox Code Playgroud)
编译为C++会发出警告:
$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
long i = i;
Run Code Online (Sandbox Code Playgroud)
在两种情况下,变量i似乎都是0,尽管在c ++中它可能是未初始化的.我实际上在我的一个功能中犯了这样的错字,很难找到它.我该怎么做才能避免这种情况?我希望至少有一个警告.此外,Clang在任何一种情况下都不会给出任何警告(c或c ++).是否有标准的特定部分说明了这种行为?
编辑:尝试了类似的东西:
$ cat 1.c
int main(void)
{
int k = k + 0;
int i = i + 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
警告(在C中)仅针对"i"生成.
$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: …Run Code Online (Sandbox Code Playgroud) 在我当前使用 MISRA 2004 标准的项目中,我们使用三个 GCC 编译器,版本 3.2.3、4.4.2 和 5.4.0。
我们使用 pedantic switch 和 c89 标准以及其他一些限制来运行构建检查。限制之一是所有数据必须在声明时初始化。
我有一个问题,在 GCC 3.2.3 上,通用零初始值设定项{0}只编译基本单一类型的数组。如果我有一个结构数组,那么我会收到一个缺少大括号的警告,并且只有当我更改{0}为{{0}}.
struct my_type my_thing[NUMBER_OF_THINGS] = {0};
Run Code Online (Sandbox Code Playgroud)
变成
struct my_type my_thing[NUMBER_OF_THINGS] = {{0}};
Run Code Online (Sandbox Code Playgroud)
但是,这对于具有结构成员的结构数组不起作用。然后问题出在 4.4.2 编译器上,它会导致缺少初始化程序错误,所以我必须这样做:
struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0}};
Run Code Online (Sandbox Code Playgroud)
这满足编译器的要求,但它会触发我们的 MISRA 检查器,因为 MISRA 需要通用单个 {0} 初始化程序或完整的全数组初始化程序:
struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0},
{0, 0, {0}, 0}};
Run Code Online (Sandbox Code Playgroud)
这对我们来说是不切实际的,因为我们有各种各样的限制,并且NUMBER_OF_THINGS …
我刚刚看到嵌入式c语句(dsPIC33)
sample1 = sample2 = 0;
Run Code Online (Sandbox Code Playgroud)
这意味着什么
sample1 = 0;
sample2 = 0;
Run Code Online (Sandbox Code Playgroud)
他们为什么这样输入?这是好还是坏编码?