问题如下:
使用以写入 0 结尾的 for 循环,计算偶数之和、奇数之和,
我不知道为什么我的代码不起作用:
#include <stdio.h>
#include <stdlib.h>
int main() {
int i = 0, num[i], sum, even, odd;
for (;;) {
printf("Write a number: ");
scanf("%d", &num[i]);
if (num[i] == 0) {
break;
}
if (num[i] % 2 == 0) {
even += num[i];
} else
odd += num[i];
i++;
}
printf("Sum of even is: %d\n", even);
printf("Sum of odd is: %d", odd);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 在C++中,有些东西出现在明确定义和未定义之间.具体而言,这些被称为实现定义和未指定.现在,我对未指明的东西很感兴趣.
什么时候可以使用这些功能,什么时候应该避免?是否有正确代码的未指定行为的良好示例?在编写软件时,它是否是最佳选择?
Matt McNabb提供的定义:
未定义 - 任何事情都可能发生
实现定义 - 有限数量的结果是可能的,编译器的文档必须说明会发生什么
未指定 - 可能有限数量的结果 - 通常标准描述了可能结果的集合
定义明确 - 以上都不是
格式良好的程序 - 无错误编译的程序(可能表现出未定义的行为)
后续问题:
放松的原子是否被指定为未指定或明确定义?
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a==b,a=b,a<b);
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中输出
1 6 1
在上面的程序中,我期望输出为0 6 0.在一些编译器中,它给出了这个输出(例如Xcode),但在某些其他编译器中,它输出为1 6 1.我找不到解释.这也是序列点的情况.
考虑以下计划
main(){
int a = 5;
int b = 6;
printf("%d %d %d",a<b,a>b,a=b);
printf("%d %d",a<=b,a!=b);
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中输出
0 0 6 1 0
这个下面的程序正在给出正确的输出,我期待的是0 0 6 1 0但是为什么上面的程序在大多数编译器中没有给出输出060
编辑:原始的单词选择令人困惑.术语"象征性"比原始术语("神秘")要好得多.
在关于我以前的C++问题的讨论中,我被告知指针是
这并没有健全的权利!如果没有任何符号,并且指针是其表示,那么我可以执行以下操作.我可以吗?
#include <stdio.h>
#include <string.h>
int main() {
int a[1] = { 0 }, *pa1 = &a[0] + 1, b = 1, *pb = &b;
if (memcmp (&pa1, &pb, sizeof pa1) == 0) {
printf ("pa1 == pb\n");
*pa1 = 2;
}
else {
printf ("pa1 != pb\n");
pa1 = &a[0]; // ensure well defined behaviour in printf
}
printf ("b = %d *pa1 = %d\n", …Run Code Online (Sandbox Code Playgroud) 如果我这样写:
i = i++, i, i++;
Run Code Online (Sandbox Code Playgroud)
它是C语言中未定义的行为.
但是,如果我这样写:
return i++, i, i++; // Is it UB?
Run Code Online (Sandbox Code Playgroud)
是不确定的行为?
例:
#include <stdio.h>
int f(int i)
{
return i++, i, i++; // Is it UB?
}
int main() {
int i = 1;
i = i++, i, i++;
i = f(i);
printf("%d\n",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 有没有一种方法可以强制gcc检测所有未定义的行为?我希望它检测在编译时和运行时都可以发现的东西。我知道UB不仅有助于简化编译器的创建,而且使编译器可以优化代码。后者在您进行调试时不相关,并且轻量级编译器的需求已不像1972年那样大。此外,gcc在这一点上是一个非常成熟的编译器,如果可能的话,它将进行大量调试工作更轻松。
我知道这-Wformat将对printf("%d", 42)未初始化的变量产生警告。当您尝试访问数组外部的内存时,该参数-Warray-bounds 可能会捕获,尽管我需要在构造实际上产生警告的代码中进行一些工作。我也知道可以使用检测到一些运行时错误-fstack-protector-all。
所以我的问题就是这样。有没有办法保证所有UB都能被检测到,如果可能的话,在编译时,但是最迟在运行时才被检测到?
我在范围内进行了变量b(范围外的声明)的类型转换,并为b赋予了新的val,当范围结束时,b的val似乎是错误的。
这是在我的Macbook上发生的,它的gcc版本是gcc-8(Homebrew GCC 8.3.0)8.3.0。我在gcc版本为5.4.0的linux笔记本电脑上尝试了相同的代码,并且代码运行良好。
std::vector<int> a = {1,2,3,4};
int b;
{
size_t i = 0, b = a[i];
//this time type of b is size_t
++i;
b = a[i];
}
std::cout << "b = " << b << std::endl;
Run Code Online (Sandbox Code Playgroud)
在我的Mac上,结果是b = 0
在Ubuntu 16上,结果是b = 1
类型转换的两个版本的gcc有什么区别?
还是一个错误?
我正在尝试评估这一点,即使它很简单,我似乎也无法理解它。我得到了 16,但提供的答案是 12。我不明白这怎么可能是 12。
我--x首先这样做了,所以首先y是 4,然后我需要乘以x--,但它也会是 4,因为它是在之后评估的,并且x之后会递减到 3。所以4*4 = 16。
有人可以解释我的推理有什么问题吗?
int x, y;
x = 5;
y = --x * x--;
std::cout << y;
Run Code Online (Sandbox Code Playgroud) 返回ref时是否为未定义的行为.到一个局部变量?
int & func(){
int x = 10;
return x;
}
int main() {
int &y = func();
cout << y << endl;
}
Run Code Online (Sandbox Code Playgroud) 我正在运行以下代码,其中我声明了一个动态2D数组,然后继续在列索引处分配值高于实际为动态数组分配的数字列.但是,当我这样做时,代码运行完美,我没有得到错误,我相信我应该得到.
void main(){
unsigned char **bitarray = NULL;
bitarray = new unsigned char*[96];
for (int j = 0; j < 96; j++)
{
bitarray[j] = new unsigned char[56];
if (bitarray[j] == NULL)
{
cout << "Memory could not be allocated for 2D Array.";
return;// return if memory not allocated
}
}
bitarray[0][64] = '1';
bitarray[10][64] = '1';
cout << bitarray[0][64] << " " << bitarray[10][64];
getch();
return;
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出的链接在这里(值实际上是准确分配的,但不知道为什么).
c++ pointers undefined-behavior dynamic-memory-allocation visual-c++