C语言初学习——易错点合集(持续更新中)
转义字符
例题一
int main()
{
char s[] = "012xy\08s34f4w2";
int i, n = 0;
for (i = 0; s[i] != 0; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
n++;
}
}
printf("n=%d\n", n);
}
输出:
——
n=3
——
例题二
int main()
{
char s[] = "\01234";
for (int i = 0; s[i]; i++)
{
printf("1");
printf("%c\n", s[i]);
}
}
输出:
——
1
13
14
——
总结:
八进制值的判断取决于后续是否为合法的八进制。
以\开始,最少1位,最多3位,且必须是合法的8进制数字,即0~7,如"\012"。
例:在"\08"中,’\0’为结束符。
自增与自减
例题一
int main()
{
int k = 5, n = 4;
while (k--)
{
printf("%d\n", k -= 1);
}
printf("---------\n");
while (--n)
{
printf("%d\n", --n);
}
}
输出:
——
死循环
——
总结:
自增与自减也同样应用在循环体判断里,后置--时先根据当前值进行判断,是否进入循环体,再改变自身的值,最后执行循环体语句。
例题二
int main()
{
int a = 0;
printf("%d %d %d %d", ++a, a, a++, ++a, a);
}
输出:
——
3 3 1 3
——
总结:
在C语言中有个很常用的函数printf,使用时从右向左压栈,依次从右向左开始计算,计算完后才会往%d中输出,因为有多条赋值语句,所以它是个累加过程,直到压栈结束后输出最终得累加值,而遇到a++这种先使用再变化的量则优先输出。
参考:
https://blog.csdn.net/weixin_43919932/article/details/88544728
问:
#include <stdio.h>
main()
{
char a[] = "abc", *t;
int m = 3, j = 0;
while (j < m)
{
t[j] = a[j++];
// j++;
printf("%d\n", j);
printf("%c, %c\n", t[j], a[j]);
}
printf("%s\n", t);
printf("%d\n", j);
t[j] = 0;
printf("%s", t);
}
输出:
——
a, b
1
b, c
2
c,
3
abc
3
ab
——
疑问:
为什么t[j]的索引j的值在a[j++]之后没有改变?
指针
例题一
main()
{
int m = 0;
int *n = &m;
printf("value:%d\taddress:%d\n", m, &m);
*n += 1;
printf("value:%d\taddress:%d\n", *n, n);
*n++;
printf("value:%d\taddress:%d\n", *n, n);
}
输出:
——
value:0 address:6422036
value:1 address:6422036
value:6422040 address:6422040
——
总结:
因为后置 ++ 运算符的优先级高于 * ,所以在编译器的语句实际上是:*(n++);
问:浮点数
例题一
float fun(float h)
{
return (int)(h * 100) / 100.0;
}
main()
{
printf("%f\n", fun(22.223000));
printf("%f", (int)(22.223000 * 100) / 100.0);
}
输出:
——
22.219999
22.220000
——
疑问:
为什么相同的操作,使用函数进行封装后导致了精度缺失
精度缺失
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> bins = {1000000, 1000000, 1000000}; // 示例数据
long long ans = 0;
for (int i = 0; i < bins.size(); ++i) {
// 下面的计算可能会导致 int 溢出,因为进行的是 int 乘法
ans += i * bins[i] * i; // 先计算 i * bins[i],结果为 int,可能导致溢出
}
return 0;
}
输出:
——
runtime error: signed integer overflow
——
总结:
C++ 中进行算术运算时,运算符(如 * 和 +)会根据参与运算的操作数的类型来选择适当的类型。对于整型(例如 int 类型),即使结果存储在 long long 中,参与运算的 int 类型数字在计算时仍然保留其原有的 int 类型。