我在运行下面的代码时弄乱了指针和const:
int main()
{
const int test = 10;
int *ptr = &test;
printf("%d\n", test);
*ptr = 1;
printf("%d\n", test);
}
Run Code Online (Sandbox Code Playgroud)
在 Mac 上,结果为:
10
10
Run Code Online (Sandbox Code Playgroud)
在linux机器上:
10
1
Run Code Online (Sandbox Code Playgroud)
为什么更改值在 Mac 上不起作用?两台机器都使用 gcc 编译代码。
今天发现VS2010不支持roundC++项目中的功能.有关该功能的信息已在此处找到.还注意到也没有trunc功能.
所以尝试了一些东西并注意到一些可能有助于这种情况的行为.
float a = 2.999;
int b = (int)a; //gives 2
Run Code Online (Sandbox Code Playgroud)
float a = -2.999;
int b = (int)a; //gives -2
Run Code Online (Sandbox Code Playgroud)
这可以作为截断,所以我可以使用它,但是我不想使用导致未定义行为的代码.所以想问一下这是定义的还是未定义的行为.
编辑:因为我正在使用VS2008,所以我不会问C++ 11.
有许多声称使用未初始化的变量会调用未定义的行为(UB).
仔细阅读文档,我无法验证该声明,因此我想要一个令人信服的论据,为C和C++澄清这一点.
我期望两者都有相同的语义,但我准备对微妙或不那么微妙的差异感到惊讶.
使用未初始化变量开始的一些示例.请根据需要添加其他人,以解释他们未涵盖的任何角落案例.
void test1() {
int x;
printf("%d", x);
}
void test2() {
int x;
for(int i = 0; i < CHAR_BIT * sizeof x)
x = x << 1;
printf("%d", x);
}
void test3() {
unsigned x;
printf("%u", x); /* was format "%d" */
}
void test4() {
unsigned x;
for(int i = 0; i < CHAR_BIT * sizeof x)
x = x << 1;
printf("%u", x); /* was format "%d" */
}
Run Code Online (Sandbox Code Playgroud) 今天我重新审视了Pre Increment和Post Increment.
我知道的基本定义.
预增量 - 增加值并返回值.
后递增 - 递增值并在递增之前返回值.
但是做一些他们的组合我很难过.
使用基本的C程序,这是我测试的.
最初i = 0.
第一次测试
printf("%d %d",++i,++i);
Run Code Online (Sandbox Code Playgroud)
输出继电器:
2 2
Run Code Online (Sandbox Code Playgroud)
我期望:
1 2
Run Code Online (Sandbox Code Playgroud)
第二次测试
printf("%d %d",i++,i++);
Run Code Online (Sandbox Code Playgroud)
输出继电器:
1 0
Run Code Online (Sandbox Code Playgroud)
我期望:
0 1
Run Code Online (Sandbox Code Playgroud)
第三次测试
printf("%d %d",i++,++i);
Run Code Online (Sandbox Code Playgroud)
输出继电器:
1 2
Run Code Online (Sandbox Code Playgroud)
我期望:
0 2
Run Code Online (Sandbox Code Playgroud)
第四次测试
printf("%d %d",++i,i++);
Run Code Online (Sandbox Code Playgroud)
输出继电器:
2 0
Run Code Online (Sandbox Code Playgroud)
我期望:
1 1
Run Code Online (Sandbox Code Playgroud)
我认为评估可能来自右侧或左侧.在Post增量的情况下,如果是Pre Increment,则可能是左边的.也许Pre Increment的优先级高于Post增量.一些与结果相匹配的想法,但在一次测试中做出的假设并不能解释其他输出.
我从C编译器得到以下测试代码的asm代码错误.这是由于未定义的行为?
void SimulatedTest(void)
{
if ( (a) || (b && c || d) == 1 )
{
i = 2;
}
else
{
i = 4;
}
}
Run Code Online (Sandbox Code Playgroud)
标准说:
6.5.16分配操作员
操作数的评估顺序未指定.如果尝试修改赋值运算符的结果或在下一个序列点之后访问它,则行为未定义
C运算符优先规则
- ()
- ==
- || &&
对于问题情况:if((a)||(b && c || d)== 1)编译器按以下顺序计算表达式并生成错误的代码
1.(b && c || d) - > R1
2.R1 == 1 - > R2
3.(a)|| R2
但是,编译器会为以下情况生成正确的代码
案例1 : . 当没有关系'=='操作时
if ( (a) || (b && c || d) )//compiler generates expected code
Run Code Online (Sandbox Code Playgroud)
情况2:为逻辑OR运算添加括号时 …
所以我试图获得数组的价值,我设法找到了这样做的方法.当我单独使用该代码时,它运行良好,但是当我尝试将它集成到函数或宏中时,值会溢出,并且我会得到像4561033这样的东西.
这是我目前的代码:
__inline int sizeOfArray(BYTE lpArray[]) {
if(lpArray)
return (*(&lpArray + 1) - lpArray);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为这就是所谓的"未定义行为",但我不知道这意味着什么,以及如何解决它.任何想法都会受到好评.
我试图了解是否存在一种在处理指针时检查C中特定地址处变量类型的实现。
假设我们有以下代码:
Car car1; // variable of type Car in memory at address 0x100
Fruit fruit1; // variable of type Fruit at address 0x104
Car *pCar1; // pointer of type Car at address 0x108
pCar1 = &car1; // The type of the pointer matches the type of the variable, nothing special
Run Code Online (Sandbox Code Playgroud)
现在,我尝试进行手动地址处理,但没有任何错误。但是,由于类型不匹配,程序在运行时崩溃。
pCar1 = (Car *) 0x104; // Note I am deliberately offering a Fruit address and it works without build errors
Run Code Online (Sandbox Code Playgroud)
如何防止这种情况发生?有没有使这种愚蠢的失败保护机制或技术?
参考C11 草案,第 3.4.3 节和C11 草案,第 H.2.2 节,我正在寻找实现除有符号整数的模运算以外的行为的“C”实现。
具体来说,我正在寻找这是默认行为的实例,可能是由于底层机器架构。
这是一个代码示例和终端会话,说明了有符号整数的模算术行为:
overflow.c:
#include <stdio.h>
#include <limits.h>
int main(int argc, char *argv[])
{
int a, b;
printf ( "INT_MAX = %d\n", INT_MAX );
if ( argc == 2 && sscanf(argv[1], "%d,%d", &a, &b) == 2 ) {
int c = a + b;
printf ( "%d + %d = %d\n", a, b, c );
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
终端会话:
$ ./overflow 2000000000,2000000000
INT_MAX = 2147483647
2000000000 + 2000000000 …Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
#define CHAR_ROW_SIZE 4
int charTable[CHAR_ROW_SIZE ][2] = {
{'X', 'Z'},
{'J', 'L'},
{'F', 'C'},
{'A', 'B'}
};
int main()
{
printf("char element %c\n", charTable[3][1]); //fine
printf("char element %c\n", charTable[3][8]); // accessing 4th row's 9th element which is not valid
printf("char element %c\n", charTable[85][0]);// accessing 86th row's first element which is not valid
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
char element B
char element
char element
Run Code Online (Sandbox Code Playgroud)
根据我的理解,C\C++ 实际上并没有对数组进行任何边界检查。这取决于操作系统以确保您正在访问有效的内存。所以这是未定义的行为。
但是在这里我可以在不同的机器上看到相同的行为。即程序不会随时崩溃。
考虑下面的代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
vector<int> a(n);
int sum = 0;
for (auto &it : a) {
cin >> it;
sum += it;
}
cout << sum << "\n";
for (int i = 0; i < n; i++) {
cout << a[i] << " ";
}
cout << endl;
}
Run Code Online (Sandbox Code Playgroud)
输入类似(或任何大于 INT_MAX 的值到 k 中)
5 1234567891564
1 2 3 4 …Run Code Online (Sandbox Code Playgroud)