C语言常见错误
1、链式比较
int main()
{
int a = 3;
if (0 < a < 3)
printf("%d\n", a);
return 0;
}
在C语言中,条件表达式 if (0 < a < 3) 的写法并不会按预期的方式工作。这是因为C语言不支持链式比较(即,不支持 a < b < c 这样的表达式)。这样的表达式实际上会被解释为 (0 < a) < 3,其中 0 < a 的结果是一个布尔值(在C语言中,这是一个整数,0 表示 false,非零值表示 true)。
在这个例子中,因为 a 的值是 3,所以 0 < a 的结果是 true,这在C语言中会被转换为整数 1。然后,这个 1 会与 3 进行比较,即 1 < 3,这同样是 true(在C语言中为 1)。但是,这并不是想要检查的条件(即 a 是否在 0 和 3 之间,但不包括 3)。
使用逻辑与操作符 && 来明确指定两个条件:
int main()
{
int a = 3;
if (0 < a && a < 3)
printf("%d\n", a);
return 0;
}
2、地址的自增
在C语言中,您不能直接对数组名(例如a)进行自增操作(a++),因为数组名实际上是一个指向数组首元素的常量指针(在某些上下文中),C语言中不允许对左值进行"++"操作,尝试对数组名进行自增操作会导致编译错误。
int main()
{
char a[] = "abcd";
a++;
}
正确的操作应该需要使用指针来索引
int main()
{
char a[] = "abcd";
char *p = a;
p++;
}
3、段错误
- 试图修改只读内存区域中的字符
int main()
{
char *p = "abcde";
p[0] = 'z';
}
在这段代码段中,char *p = "abcde"; 声明了一个指向字符串字面量 "abcde" 的指针 p。字符串字面量在C语言中通常是存储在只读内存区域(如文字常量区或称为字符串常量池)的,尝试修改这样的字符串字面量会导致未定义行为(Undefined Behavior, UB),并且很可能在运行时导致程序崩溃或数据损坏。
具体来说,尝试执行 p[0] = 'z'; 将会试图修改只读内存区域中的字符,这是不被允许的。大多数现代操作系统和编译器会保护这样的内存区域,以防止程序错误地修改它们。
如果想要修改字符串的内容,应该使用字符数组而不是指向字符串字面量的指针,如下所示:
int main()
{
char p[] = "abcde";
p[0] = 'z';
}
- 越界访问
int main()
{
int a[3] = {1, 2, 3};
a[4] = a[2];
}
在这段代码段中,定义了一个整数数组 a,它的大小是 3,并用三个值 {1, 2, 3} 初始化。然后您尝试访问和修改 a[4],但这是一个数组越界访问(Array Out-of-Bounds Access)。
在C语言中,数组索引是从0开始的,所以对于一个大小为3的数组 a,有效的索引范围是 0 到 2。尝试访问 a[4] 是未定义行为(Undefined Behavior, UB),因为您正在访问数组分配的内存之外的区域。
未定义行为可能导致程序崩溃、数据损坏、意外的程序行为或任何其他不可预见的结果。在某些情况下,它甚至可能看起来像是在正常工作,但这是一个危险的陷阱,因为代码可能在不同的编译器、不同的操作系统或不同的优化设置下表现出不同的行为。
- 指针退化
void func(int array[])
{
int len = sizeof(array) / sizeof(int);
}
在C语言中,函数参数中的数组名(例如int array[])会退化为指向数组第一个元素的指针。因此,在函数func内部,array不再是一个数组,而是一个指向int的指针。
由于array只是一个指针,它不再包含有关数组原始大小的信息。所以,当你试图使用sizeof(array)时,你得到的是指针的大小,而不是整个数组的大小。在不同的系统和架构中,指针的大小可能会有所不同(通常是4字节或8字节,取决于系统是32位还是64位)。
因此,在函数func中,sizeof(array) / sizeof(int)并不会给你数组的实际长度。为了解决这个问题,你通常需要在调用函数时传递数组的长度作为另一个参数,如下所示:
void func(int array[], int len)
{
}
标签:错误,int,常见,C语言,数组,array,main,指针
From: https://www.cnblogs.com/Dazz24/p/18176016