C语言深度解剖记录

C语言深度解剖记录

前言

一上来肯定要吹逼了,当鸡汤了,振奋一下自己。

第一章 关键字

  • 声明和定义的区别:创建对象并分配内存,是定义;否则为声明。

感觉分这么细也没啥用

  • register寄存器变量,速度快,必须是单个的值,长度小于等于整型的长度,register可能不在内存中,不要用&获取它的地址

没用过。不用&获取地址,第一次知道

  • static

和之前了解的没什么分别

  • 数据类型的作用,把它比喻成了模子,差不多吧

  • 变量的命名规则 介绍的类似匈牙利法的命名规则,有前缀、后缀。看看谷歌 kernel的说明吧。链接如下:

    https://www.kernel.org/doc/html/v4.10/process/coding-style.html

    https://google.github.io/styleguide/cppguide.html

  • 不要用8进制 确实,平时不怎么用,也不容易分清8进制具体的值,还是十进制和十六进制香

  • sizeof是关键字, 函数求值是在运行时,sizeof求值是在编译时,不明觉厉

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xrkZfhx7-1638170548779)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129091755990.png)]

从上往下的结果: 4 4 400 4数组溢出但不出错,编译时运行的内容 4 4 4

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2dHD9iDl-1638170548789)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129095422306.png)]

结果是255 因为a[255] = 0

考察补码,对补码不是很熟,不能第一时间反应过来

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hyxCaiQ5-1638170548793)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129095654200.png)]

正0 负0 都是 0000 0000 -20转为无符号数,10010100为148 +10 = 158 或236+ 10=246

还有一个问题 死循环,无符号整数 条件是大于等于0

  • 布尔变量与0值比较,书中的意思是不要判断变量是0还是1,写成 if( isFlag )这样的形式

感觉有些多余,因为单片机里虽然兼容C99标准,但是很少使用布尔变量,多用0表示假,非0表示真。就算在vs2019里也得包含stdbool才能使用布尔量。

  • 浮点数和0比较,常见的fabs(相减)<=实现定好的值,float一般是1e-6就行
  • 指针和0比较,用NULL,但是C++里,值是一样,但是这样看起来更好 p != NULL
#ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
  • 1.7.4——1.7.6 介绍了一堆if else 和编程风格,大括号换行的问题,和google正相反,无所谓了
  • 1.8 switch case语句 case后面只能是整型或字符型的常量或常量表达式,容易忘,但是平时用的时候很少主动用其他的
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qja2XT5I-1638170548796)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129102352763.png)]

这个问题还真不确定,应该是0吧

  • const 别把它当成常量,当成只读变量吧。不能用在switch语句里。应该属于RO data

    修饰指针的时候,const和谁近就修饰谁。const也可以用在函数参数或者函数返回值

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gWkW949Q-1638170548799)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129112535886.png)]

  • volatile:防止编译器优化,必须要去内存中取这个值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShNxVZW0-1638170548801)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129104258181.png)]

  • 1.15 extern 1.16 1.17

extern是声明 柔性数组的概念,不常用,用到再看 union,会判断大小端即可 位域用的比较少,但是挺复杂

  • enum 枚举成员里是枚举常量,枚举常量的值为整型常量表达式
  • 1.19 typedef
typedef struct stu
{
	int score;
	int age;
}STU,*STU_P;//一个是结构体变量,一个是结构体指针
int main(void)
{
	STU stutest;
	const STU_P stu3;
	STU_P	const	stu4;
	stu3 = &stutest;//用了typedef,不是替换,如果是替换,const修饰stu3 stu4指向的内容,不能改变;现在STU_P作为整体是一个类型,const修饰stu3 stu4,即指针本身不能被修改,所以修改这两行会报错,下面的赋值不会报错
	stu4 = &stutest;
	stu3->age = 22;
	stu3->age = 90;
	printf("%d  %d\n", stu3->age, stu3->score);
}
typedef static int int32;不对,vs报错不能指定多个存储类

typedef和复杂的声明在一起,挺麻烦,复杂的声明总是心里没底,不敢保证每一次都对,1.19.4后面是一堆习题,测试typedef和#define,有时间再做

第二章 符号

2.4逻辑运算符

逻辑运算符的短路效应,运算符有函数调用的话,把函数调用作为第一个操作数,因为有短路效应,一旦另一个操作数可以判断出整个逻辑表达式的结果,那么这个函数调用可能就不会执行。如下,函数func有可能不执行

if( x==1 && func() )

2.5位移运算符

书中位移运算符介绍的不太好,有点乱。有一个例子不理解

image-20211129133322521

uint8_t已经是8为了,为什么会变成0xffa5呢?在stm32上这样写过,没什么问题啊。在vs2019里用如下代码测试,也正常

	typedef unsigned char uint8_t;
int main(void)
{
	uint8_t   port = 0x5a;
	uint8_t   result_8 = (~port) >> 4;
	printf("%x", result_8);

}

2.7++ --操作符

搞了一堆++i+++i+++i,头大,好像是UB,没必要吧

2.8 2/(-2)

作者没有给答案,写了一堆,有点故弄玄虚。VS2019运行,2 / (-2) == -1 2 % (-2)==0.

2.9 优先级

给出了优先级表和常见容易出错的地方

第三章 预处理指令

3.1 宏定义

介绍了挺多,挺详细的,但是用不上啊。反斜杠换行,do-while语句,多用小括号

3.2——3.5

条件编译,文件包含,用过,没什么特殊。#error没用过 #line没用过

3.6 #pragma

pragma的用法真是好复杂啊,现在用到的就是结构体对齐,image-20211129142205461

3.7# 和##

在别的地方看过,这两个的用法比书上写的复杂一些,之前看的有些懵。一个是把宏定义里的字符串变成值,第二个是拼接,尤其是带参数的宏,更麻烦

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcoXkl4g-1638170548810)(C:\Users\fj2021\AppData\Roaming\Typora\typora-user-images\image-20211129142608589.png)]

第四章 指针和数组

4.1指针与内存布局

举了个例子,但是在vs2019里执行不了,在指定位置写入值,这时候程序执行不了,理解作者的想法就行了

4.2数组

用省政府和市政府类比了&a[0]和&a的区别。步长不同,一个是数组首元素的地址,一个是数组首地址

数组名a可以作为右值,不能左值

4.3指针和数组

指针是指针,数组是数组 数组指针和指针数组,可以理解

char a[5] = { 'A','B','C','D','E' };
	char(*p3)[5] = &a;
	char(*p4)[5] = a;
	printf("a=%p p3=%p p4=%p\n", a, p3, p4);
	printf("a=%p p3+1=%p p4+1=%p\n", a, p3+1, p4+1);
image-20211129151012267
char a[5] = { 'A','B','C','D','E' };
	char(*p3)[3] = &a;
	char(*p4)[3] = a;
	printf("a=%p p3=%p p4=%p\n", a, p3, p4);
	printf("a=%p p3+1=%p p4+1=%p\n", a, p3+1, p4+1);
image-20211129151105096
char a[5] = { 'A','B','C','D','E' };
	char(*p3)[10] = &a;
	char(*p4)[10] = a;
	printf("a=%p p3=%p p4=%p\n", a, p3, p4);
	printf("a=%p p3+1=%p p4+1=%p\n", a, p3+1, p4+1);
image-20211129151209910

根据测试结果,p3+1 p4+1增加对应的步长

image-20211129151939692

地址的强制转换,第一个没问题,第二个一开始弄错了,+1之后不是数组的第二个元素,而是从第一个元素的第二个字节开始,往后数4个字节,作为一个int,这样*ptr2的值取决于大小端了

image-20211129152046514

题,第二个一开始弄错了,+1之后不是数组的第二个元素,而是从第一个元素的第二个字节开始,往后数4个字节,作为一个int,这样*ptr2的值取决于大小端了

image-20211129152046514

可以根据图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值