
记录学习过程中错误、混淆的 C 语言知识点,持续更新……
第 1 题:^ 和 << 的优先级
设有以下语句:
1 | char a = 3, b = 6, c; |
则 c 的二进制值是 ______。
❌ 我的错误答案:0100(即十进制 4)
错误原因:混淆了^和<<的优先级,误以为按位异或先于左移,于是先计算a ^ b,再左移 2 位。✅ 正确解析:在 C 语言中,左移运算符
<<的优先级高于按位异或^,所以原式等价于a ^ (b << 2)。
计算过程:6 << 2 = 24(二进制11000),3 ^ 24 = 27(二进制11011)。正确答案:
11011(十进制 27)
第 2 题:结构体指针与成员访问
根据以下定义,错误的表达式是:
1 | struct { int a; char b; } Q, *p = &Q; |
❌ 我的错误倾向:容易混淆
*p.b与(*p).b,忽略了成员运算符.的优先级高于解引用*。✅ 正确解析:成员访问运算符
.的优先级高于解引用运算符*,因此*p.b会被解析为*(p.b)。但p是指针,不能直接用.访问成员,必须写作(*p).b或p->b。正确答案:D.
*p.b
第 3 题:结构体首地址与强制类型转换
分析以下代码的运算结果:
1 | struct node { |
❌ 我的错误答案:6
错误原因:误以为指针pt指向结构体的末尾(成员c),实际上指针存储的是结构体的首地址。✅ 正确解析:结构体在内存中连续分布,其首地址即第一个成员
a的地址。(int *)pt将结构体指针强转为整型指针,解引用后读取从首地址开始的int大小数据,正好是成员a的值。正确答案:3
第 4 题:冒泡排序实现
用 C 语言对数组 a[10] = {6, 2, 8, 11, 0, 7, 3, -3, 9, 12} 进行升序排列。
❌ 我的错误状态:对排序算法的双重循环逻辑不熟练,不知道如何通过嵌套循环实现元素比较与交换。
✅ 正确解析(冒泡排序):核心思想是两两比较相邻元素,如果反序则交换,每轮将当前最大值“冒泡”到数组末端。
完整代码:
1 |
|
运行结果:-3 0 2 3 6 7 8 9 11 12
第 5 题:转义字符 '\101'
若有定义:char c = '\101'; 则变量 c 中包含的字符个数为多少,是哪些字符?
❌ 我的错误答案:1,5。错误认为是二进制转十进制。
✅ 正确答案:1,A。
遇到\数字,就是八进制;\x才是十六进制。'\101'表示八进制数101,转换为十进制是65,对应 ASCII 字符'A'。
第 6 题:输入年份,判断是否闰年
输入一个年份,判断该年份是否为闰年。
✅ 核心知识点:闰年判断条件
满足以下任意一个条件,就是闰年:
- 能被 4 整除,但不能被 100 整除;
- 能被 400 整除。
对应的 C 语言逻辑表达式为:
1 (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
完整代码:
1 |
|
第 7 题:&&中若左假的重点(同理||也是)
a=5,b=6,c=7,d=8,m=2,n=2,求(m=a>b)&&(n=c>d)后n的值。
答案:C) 2
重点:a>b为假,m=0,&&短路,右边不执行,所以n仍为2。
第 8 题:运算符了解一下该点即可
a=12,求a += a -= a *= a后a的值。
答案:a=0
重点:从右向左且a同时改变:a*=a后a=144;a-=144后a=0;>a+=0后a=0。
第 9 题:指针下标越界
若有以下定义,则对
a数组元素的正确引用是( D )。int a[5], *p = a;
A)*&a[5](下标越界)
B)a + 2(不是元素,是地址&a[2])
C)*(p + 5)(下标越界)
D)*(a + 2)(正确,等价于a[2])
答案:D
注意:没注意下标越界
第 10 题:二维数组a中的*(a + j)
若有定义:
int a[2][3];,则对a数组的第i行j列元素地址的正确引用为( D )。
A)*(a[i]+j)
B)(a+i)
C)*(a+j)(得到的是a[j][0]的地址)
D)a[i]+j
答案:D
注意:*(a+j)等价于a[j](这里的j相当于行下标了)。
第 11 题:printf("%ld")输出地址(能打印,但不规范)
下面程序段的运行结果是( C )。
1
2
3 >char *s = "abcde";
>s += 2;
>printf("%ld", s);A)
cde
B) 字符'c'
C) 字符'c'的地址
D) 无确定的输出结果
答案:C
注意:printf("%ld", s)试图以十进制长整型不规范来输出s的值,也就是字符'c'的地址。
第 12 题:16进制地址的加法
以下程序段的执行结果是:
2016 2041
1
2
3
4
5 >unsigned char *p1;
>unsigned long *p2;
>p1 = (unsigned char *)0x10002011;
>p2 = (unsigned long *)0x10002021;
>printf("p1=%p,p2=%p", p1 + 5, p2 + 4);答案:
p1=0x10002016,p2=0x10002041,低四位为2016 2041
注意:0x表示16位,0x中一个数是由4位组成,p1是unsigned char *,加 5 移动 5 字节,得到0x10002016;p2是unsigned long *,加 4 移动4 * sizeof(unsigned long)字节。若unsigned long占 8 字节,则移动32字节,即0x20,得到0x10002041。
第 13 题:++与(…++)
以下程序段的执行结果为
7 8。
1
2
3
4
5 >int arr[] = {6, 7, 8, 9, 10};
>int *ptr = arr;
>*(ptr++) += 123;
>printf(" %d", *ptr);
>printf(" %d", *(++ptr));答案:
7 8
注意:++与括号无关,就算有括号,也是先用它的值。*(ptr++) += 123先取ptr当前指向的arr[0],将其值加123,然后ptr自增指向arr[1]。所以arr[0]变为129,*ptr输出arr[1]的值7;*(++ptr)先让ptr自增到arr[2],再解引用,输出8。
第 14 题:C 语言程序的组成
一个 C 语言程序是由 ______。
A. 一个主程序和若干个子程序组成
B. 函数组成
C. 若干过程组成
D. 若干子程序组成
❌ 我的错误答案:A
错误原因:把其他语言里“主程序 + 子程序”的说法套到了 C 语言上,也忽略了 C 程序可以只有一个main函数。✅ 正确解析:C 语言程序的基本组成单位是函数。一个 C 程序由一个或多个函数组成,其中必须有且仅有一个
main函数(主函数),程序从main函数开始执行。其他函数可以被调用,也可以没有。注意:C 语言中没有“过程”这种标准说法;选项 A、D 的“主程序 / 子程序”也不是 C 语言的规范表述。
正确答案:B. 函数组成
.char str[] = “Hello”; sizeof ( str )= 6
char *p = str ; sizeof ( p ) = 8
int n = 10; sizeof ( n ) = 4
void Fun(int a[5])
{ sizeof(a)=8 //填成20了
}
第 15 题:sizeof 计算数组与指针
1 | char str[] = "Hello"; |
❌ 易错点:把
Fun中的sizeof(a)填成 20。
✅ 正确解析:函数参数中的int a[5]会退化为int *a,sizeof(a)计算的是指针大小。
64 位系统为 8,32 位系统为 4,不是数组总大小 20。
第 16 题:统计字符出现次数(不区分大小写)
题目:输入一个由字母和数字组成的字符串,接着输入一个字符。输出该字符在给定字符串中的出现次数,不区分大小写(借助函数实现)。
1 |
|
第 17 题:统计单词个数
题目:用户输入一段字符串,并统计其中的单词个数,假设单词之间用空格隔开,不考虑其他特殊字符。字符串最大长度不超过 1024。
1 |
|
第 18 题:寻找数组中的“幸运数”
题目描述:在一个整数数组中,如果一个数字的出现次数恰好等于它本身的值,我们就称这个数字为“幸运数”。例如,在数组 {1, 2, 2, 1, 3, 3} 中,数字 2 出现了 2 次,所以 2 是幸运数。请编写一个 C 语言程序,实现找出幸运数字中最大的那个,没有就显示“没有幸运数字”。
1 |
|
说明:使用两个
for循环统计每个数字的出现次数,时间复杂度为 O(n²)。
如果数据量较大,可以用哈希表或数组下标计数优化到平均 O(n)。
持续更新中……