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

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

本章介绍

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


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地址一样;所以发生死循环

3af7d0afd9314e3992569d03c42b12d7.png


原理:

  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是正常的。


14f443d18c0f4e0c90cf0c84d0490ab5.png

15efd0aeda0fb864cc388e6c89906b2e_gtzr4r6y54wp6_597fe6878a36415ab03d0ab14ecea3bf.png


填充序列是类似小端的低地址在低位,所以排列顺序是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有无号类型的取值

3f75ce9ff19148318140f08095f318b3.png

解析


当 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

目录
相关文章
|
5月前
|
存储 Java 数据库
|
8月前
|
编译器 C语言
初识C语言
本篇旨在初步了解C语言的大概知识,并不作深入探讨。知识点会在后期的更新的文章中进行深入学习。
26 0
|
5月前
|
编译器 C语言 C++
|
28天前
|
存储 C语言
初识C语言(二)
初识C语言(二)
|
2月前
|
Java 程序员 编译器
什么是C语言
什么是C语言
22 0
|
2月前
|
BI C语言
C语言:练习1
C语言:练习1
35 2
|
9月前
|
自然语言处理 Java 编译器
你知道C语言吗?
了解C语言是什么,以及代码是怎么跑起来的,初学者必看
|
9月前
|
存储 编译器 C语言
你应该知道的C语言干货(1)
小数直接写出来编译器默认为double类型,后面加上f才是float类型
65 0
|
5月前
|
编译器 Linux C语言
|
5月前
|
存储 C语言
C语言中的&和*
C语言中的&和*
50 0