> 文章列表 > 【C语言】那些 “虾仁猪心“ 的坑题

【C语言】那些 “虾仁猪心“ 的坑题

【C语言】那些 “虾仁猪心“ 的坑题

本章介绍

最近翻笔记,整理了下那些日子里面掉过的坑题,说多都是泪!!也许是自己的储备知识不足,才造成的大坑,今天把题拿出来给大家溜溜,看大家做时候有没有踩坑!

文章目录

  • 1:第一题
  • 2:第二题
  • 3:第三题
  • 4:第四题

1:第一题

下面输出结果是什么

#include <stdio.h>
int i;
int main()
{i--;if (i > sizeof(i)){printf(">\\n");}else{printf("<\\n");}return 0; 
}

A.>
B.<
C.不输出
D.程序有问题

解析:
全局变量,没有给初始值时,编译其会默认将其初始化为0。
i的初始值为0,i - -结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该选择B,但是sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据,-1对应的无符号整形是一个非常大的数字,超过4或者8,故实际应该选择A
这道题其实很隐蔽,真是虾仁猪心!!!


2:第二题

VS开发环境调试下面的代码,画图解释下面代码的问题

#include <stdio.h>
int main()
{int i = 0;int arr[] = {1,2,3,4,5,6,7,8,9,10};for(i=0; i<=12; i++){arr[i] = 0;printf("hello bit\\n");}return 0;
}

解析:
for循环中,i的内容是从0,一直增加到12,而数组只有10个空间,因此会越界。
函数的调用首先是放在栈里的,这个栈是按照从高到低排序的,int i先定义 在上面一点,而数组在栈上排序是按数组的索引从小到大从下往上排序,所以数组可能越界访问到i,所以越界数组的地址 和i地址一样;所以发生死循环
【C语言】那些 “虾仁猪心“ 的坑题
原理:

  1. i和arr是局部变量,局部变量是放在栈区上的
  2. 栈区内存的使用习惯是,先使用高地址处的空间,再使用低地址处的空间。
  3. 数组随着下标的增长,地址是由低到高变化的

3:第三题

该题用到的知识是位段,如不清楚可以看看 -> 结构体与位段
下面代码的结果是什么?

#include<stdio.h>
int main()
{unsigned char puc[4];struct tagPIM{unsigned char ucPim1;unsigned char ucData0 : 1;unsigned char ucData1 : 2;unsigned char ucData2 : 3;}*pstPimData;pstPimData = (struct tagPIM*)puc;memset(puc, 0, 4);pstPimData->ucPim1 = 2;pstPimData->ucData0 = 3;pstPimData->ucData1 = 4;pstPimData->ucData2 = 5;printf("%02x %02x %02x %02x\\n", puc[0], puc[1], puc[2], puc[3]);return 0;
}

A. 02 03 04 05
B. 02 29 00 00
C. 02 25 00 00
D. 02 29 04 00

解析

  • struct tagPIM该结构体所占内存为2个字节,它只有第一个元素单独享用一字节,其他三个元素一起共用一字节,pstPimData指针指向了puc数组,puc数组所占内存空间为4个字节,pstPimData指向puc数组最多只能占用两个字节。puc被结构体填充后,本身只有两个字节会被写入,后两个字节肯定是0,至此AD排除。

  • 然后第一个字节是2就是2了(10),第二个字节比较麻烦,首先ucData0给了3其实是越界了,1位的数字只能是0或1,所以11截断后只有1,同理ucData1给的4也是越界的,100截断后是00,只有5的101是正常的。

【C语言】那些 “虾仁猪心“ 的坑题【C语言】那些 “虾仁猪心“ 的坑题
填充序列是类似小端的低地址在低位,所以排列顺序是02 29 00 00 即0x29
答案是->B


4:第四题

int main() 
{unsigned char i = 7;int j = 0;for (; i > 0; i -= 3) {++j;}printf("%d\\n", j);return 0;
}

下面代码的结果是什么?

A. 死循环
B. 173
C. 172
D. 3

🌙 ->知识补充
有符号char的取值范围是 127 到 -128
unsigned 无符号char的取值范围是 0 到 255
以下图是char有无号类型的取值
【C语言】那些 “虾仁猪心“ 的坑题

解析

当 i一直减3 减3,7 4 1 -2(但是i的取值范围不可能是负的,数据从于一个闭环,当我们输入0~255之间的数据之时,以0为起点,顺时针走向,与存储数据相对应,而当我们输入-1、-2、-9……的时候就会开始,以255为起点,逆时针走向,逐渐递减,分别存储255、254、247) 。

  • 所以此时i是254了 那我们递推一下,i什么时候才可以变成0,我们把254 除上一个3 等于84 余上一个2, 把2在-3我们又得到 (i等于-1)255,255在除上3等于85,余上一个0,i此时为0,此时循环结束 。
    上面我们一共进行了 3 + 84 + 1 +85 = 173 次循环。
    所以我们的j等于173

答案是B .173