C 语言避坑指南

  👉引言💎

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
热爱写作,愿意让自己成为更好的人…


在这里插入图片描述

铭记于心
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉

C 避坑指南

一、基础|基本常识类

  • 注意逻辑运算符的短路效应

  • else只跟最近的if相匹配

  • c语言本身不提供输入输出语句,靠标准函数库实现

  • putchar 输出的是字符,,c语言函数内部 不能够嵌套定义 函数

  • 存储类型 有 auto ,static , register(寄存器) , extern(外部),全局变量默认为 static

  • 未指定存储类别的变量,其隐含的存储类别为 auto

1 运算符类型
  • 对于%,需要%%才能转义,而不是\

  • 逗号运算符优先级最低,整个逗号表达式的值就是 最右边表达式的值

在这里插入图片描述

在这里插入图片描述

  • char类型对于字符串会取最低位字符

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gxaKGM9P-1661697614551)(image/image_kWF-MBinZ7.png)]

  • 这个就是 每个字符占一个字节,int4个字节,被赋值’328’后,每个字节位置则是 0 51 50 56, 换成二进制后再转换为int即为3355192

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWRroyGa-1661697614551)(image/image_57RktaQnfx.png)]

  • 只是逗号表达式返回最右边的值,执行还是从左到右

在这里插入图片描述

  • a+=a-=a*a;C中为-4 ,java中为0

    易知Java中对同一变量连续赋值,JVM虚拟机运行结果与c【-8 7 3】不同,而这种写法在python中是不被允许的

在这里插入图片描述

2 占位符|格式化问题

需要注意的是 2 转义字符的使用事项:

  • %5.2s 指输出字符串前2位,占5个空间,右对齐 %d 是忽略并丢弃一个整型字符

  • #的作用 是输出提示(0, 0x)

  • 注意对 char类型赋值时一定看清楚是 数字还是字符,6与’6’是完全不同的

  • %d%i只在scanf时有区别,且前者 只匹配十进制,不匹配的都输出0,后者据情况判断(0x十六进制,0八进制)转10进制

    不匹配直接搞成0

在这里插入图片描述

  • m.n中 m是宽度,负号表示左对齐;n是(具体跟 后面的 d(至少输出的位数) , s(输出的位数) ,f(输出的精度)有关

    不满足则 用0补齐,高位补0,想想也确实应该 [其实一般用于浮点型]

在这里插入图片描述

  • 如果是%5d 的话则输出 [空格]-123 其实这些 都是符合逻辑的,因为 总不能 下面输出0-123吧,这也不合适

在这里插入图片描述

  • 关于 字符串的输出格式化,字符串位数小于“精度”则输出全部字符串,其它不用管,,大于,则只取“精度”规定的前几个字符

    在这里插入图片描述

在这里插入图片描述

  • 对于%d来讲,4代表控制精度为4位,所以高位补0;5代表 设置宽度,所以靠右对齐,共占五个宽度

在这里插入图片描述

3 输入输出问题
  • sprintf(const char * str …),后面跟printf用法一样,就多了一个指定输出位置str

  • printf与scanf返回值都是由 输出输入字符数量决定

  • scanf(读取时的格式符不能带 .n这样是无效的,也就是只能是 %3d(读取三位有效数字), 而不能%3.2d),且输入时如果不加 输入项,则会抛出运行时异常,而printf(“dadw%d”)没有输出项也不会报异常

  • 注意如果是 scanf(“%c\n”),则输入一个字符回车会陷入死循环,因为回车(空白字符)不会被scanf读取,但是还没有读取\n,也就是他会一直去“读\n”,除非再输入一个 非空白字符

在这里插入图片描述

  • 包括 lf,f格式字符都是默认输出 小数点后六位(超过则四舍五入),但%g可以将无效位数去掉,只输出有效位

在这里插入图片描述

  • getchar( 出错返回-1)

在这里插入图片描述

二、错题 | 程序语句类

  • 1 对于 while(b- -≥0)一定注意,最后b出来的时候是-2,一定要注意这个问题

  • 2

    int s = (b = ++m * m++, --m + b--) + ++b +b--; //相当于b = ++m * m++; s = ( --m + b--) + ++b +b--;
    后置++是此运算式子中都不变,运算结束自加(逗号符可以看做结束运算),比如这个m自+后当时是m,但后来m就是m+1int s = m + m * (m++) * m;
    
    

    ,而不是语句

在这里插入图片描述

在这里插入图片描述

  • 3

在这里插入图片描述

  • 4 虽然符合c11标准,但各家编译器对其扩展定义不同,比如dev允许变长数组(变长数组不能在定义时初始化),但vs中不允许

在这里插入图片描述

  • 5

在这里插入图片描述

  • 6
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

三、进阶 | 指针与函数

scanf(),getchar(),getche(),getch()这些函数缓冲区角度的解释

字符串常量

  1. 相当于 *p = *p+6

    在这里插入图片描述

  2. 不能这样给字符数组赋值,另外,上面哪一行在vs中需要加const修饰(指向字符常量)

在这里插入图片描述

  1. 函数指针

    int (*t)(int a, int b);
    两种调用方式都是可以的
      (*t)(2, 1);
      t(2,1)
    
  2. 数组名是一个地址,也就是一个指针,但不能说是指针变量(不可变),,指针变量的值是一个地址

  3. *p=*q 解引用当左值时是变量,右值时是常量

  4. 二维数组传参时局部变量不能用 二级指针,而用数组形式,因为需要指定 一维容量,即 void test(int nums[ ][5] );,字符数组亦是如此

  5. 对于数组无法自增,但可以再用个指针指向该数组进行自增移动

    P是一个数组指针,指向空间大小为4的数组

  6. printf()多元素输出的时候,存在入栈(同时进行运算),出栈问题,一定注意

  7. strcpy会连 \0结束符 一起复制过去 而strncpy(char *dest, const char *src, size_t len)并不会负责添加‘\0’(在字符串长度大于len的情况下,如果小于则会用NULL(\0)填满)

  8. 接收含有空格的字符串直接用 gets(str),输出可以puts(str)【且自动换行】

四、进阶 | 结构体及宏定义

  1. 结构体长度的计算

    union的使用受系统大小端的影响

    栈的生长方向与内存存放规则

    低地址存低位数据
    大端模式,低地址存高位数据

在这里插入图片描述

    int check_cpu()

    {
    union{
    short a;
    char b;
    }c;
    c.a=1;
    return c.b == 1;
    }小端返回1
   enum s------------------------------izes { small=7,medium,large=10,humungous };       
   默认情况下,整型值从0开始。如果对列表中的某个标识符进行了赋值,那么紧接其后的那个标识符的值就比所赋的值大1,然后类推

在这里插入图片描述
在这里插入图片描述

3.

  • 宏定义是用宏名代替一个字符串,也就是做简单的置换,不做正确性检查。(预编译时不做任何语法检查,只有在编译已被宏展开后的源程序时才会发现语法错误并报错)

  • 宏定义不是C语句,不必在行末加分号,不是c语言本身组成部分。如果加了分号则会连分号一起进行替换

  • #definde出现在A处,则宏名的有效范围为定义命令之后到本源文件之后到本源文件结尾。

  • 可以通过#undef命令终止宏定义的作用域

  • c语言不做const char*修饰以及越界检查,并且如果是cpp,那么检不检查也与编译器有关,比如vs2022检查,dev照样不检查

  • memchr()如果找数字0,则会返回任意地址,因为它会认为0是NULL

🌹写在最后💖
路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想new的出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值