C语言深度解剖重读

1.关键字类

1.register

作用:请求编译器尽可能将变量存在CPU内部的寄存器(寄存器数量是有限的,因此是尽可能)

        寄存器:小的存储空间,存取速度比内存快很多,离CPU近

注意事项

        1.register变量要是CPU寄存器接受的类型,长度小于等于整型长度

        2.register变量不存在内存中,不能通过取址运算符&获取变量地址

2.static

两个作用:修饰变量和修饰函数

1.修饰变量:使得变量都存在内存的静态区

修饰局部变量:函数运行结束,静态变量的值不会被销毁,下次还能继续使用

修饰全局变量:作用域限定在本文件中(从定义开始到文件结尾处),其他文件用extern也无法使用

2.修饰函数

主要是限定函数作用域,只能在本文件中使用该函数(又称为内部函数)

3.sizeof

注意:是关键字而不是函数,也可以说是运算符

1.sizeof计算变量大小空间时,括号可以省略,计算数据类型时,括号不能省略

2.sizeof(一个指针),在32位系统中,固定为4个字节,64位系统中,固定为8个字节

例子:

int b[100]属于全局数组,数组作为函数参数时退化成指针(很重要

因此上述结果为4(32位系统)

4.break和continue

break:终止本层循环

continue:终止本轮循环

5.void

  • 注意void*(void指针)不能进行算法操作,因为没有分配内存
  • void 不能代表一个真实的变量

6.const

        可以节省空间,提高效率

        编译器通常不为普通const只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高

常问:const 和 define 的区别

7.volatile

易变、不稳定,常用于防止编译器优化

8. extern

        声明外部函数或者变量(其他源文件)

        extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中

9.struct

        多种数据整合成为一个整体

1) 空结构体内存:1Byte

2) struct 和 class 的区别:默认的成员属性不一样

struct :默认public属性

class :默认private属性

10.union

        union的空间大小为最大成员的大小,所有成员共用一个空间,同一时间只能存储一个成员,且所有成员的起始地址相同(根据此特性来写函数判断大小端

判断大小端函数

大端模式:符合人们常用的阅读习惯,高字节存在低地址上

小端模式:高字节存在高地址上

常问:union 和 struct 的区别(存储方式、初始化)

操作运算符:

算数运算符高于位移运算符

逗号运算符优先级最低

2.函数类

1.if else 组合

1.bool变量与零值比较

bool flag

推荐写法: if(flag) 或者 if(!flag)

:FALSE值在编译器中被定义为0,但是TRUE的值不一定为1,不同的编译器中不同,可能为1,也可能为-1

2. float 变量与零值比较

float x = 0.0;

推荐写法:if(x >= -EPSINON) && (x <= EPSINON);

tips: 由于float是有一定精度限制的,通过EPSINON来设置精度,如果这个数落在 [0.0 - EPSINON, 0 + EPSINON] 中,则认为和0相等

3. 指针变量和零值比较

int *p = NULL;//注意,定义指针要记得初始化,不一定非要是NULL

推荐写法:if(NULL == p) 或者 if(NULL != p)

2. switch case 组合

1. case 后面的值要求

只能是整型或字符型常量或者常量表达式(字符型本质上也是整型)

2. case 中忘记加break

当匹配到某个case时,但缺少break,则程序会一直运行之后的case知道遇到break为止

3. 指针和数组

3.1 指针

1. 基础

  • 指针是什么:存储地址的变量,指针变量 p 中存储的任何数据都被当作地址来处理
  • sizeof(p):32位系统中,固定为4byte(64位则为 8 byte),与 p 的类型无关

2. int *p = NULL*p = NULL 的区别

int *p = NULL:初始化指针变量p指针 p 的值为 0x00000000  

*p = NULL:赋值*p 的值为0,p指向的内存可能非法

注:NULL 和 NUL 的区别,NULL一般被宏定义为0,而NUL是ASCII码表的第一个字符

3.2 数组

1. 基础:

  • 定义:一组相同数据类型的元素,内存连续排布
  • int a[5],数组名 a 代表数组首元素的首地址

        sizeof(a) = 20

        sizeof(a[0]) = 4

        sizeof(a[5]) = 4  编译器不能检测数组越界,只是根据元素类型来确定值

  • &a[0] 和 &a 的区别:值相同,但意义不同

        &a[0]:数组首元素的首地址

        &a:数组的首地址

  • 数组名a 作为左值和右值

C语言引入一个术语-----“可修改的左值”。意思就是,出现在赋值符左边的符号所代 表的地址上的内容一定是可以被修改的。换句话说,就是我们只能给非只读变量赋值

1)a作为左值 !!!(不存在

编译器会认为数组名作为左值代表 的意思是a的首元素的首地址,但是这个地址开始的一块内存是一个总体,我们只能访问数组的某个元素而无法把数组当一个总体进行访问。所以我们可以把a[i]当左值,而无法把 a 当左值

2)a 作为右值

此时代表的是数组首元素的首地址,意义和&a[0]一样

3.3 指针和数组

        二者毫无关系

1)以指针形式下标形式访问指针

读取字符e

  • 指针形式:*(p+4)
  • 下标:p[4]

2)以指针形式下标形式访问数组

读取字符5

  • 指针形式:*(a+4)
  • 下标:a[4]

3)例子

         int a[5] = {1, 2, 3, 4, 5}

  • a:a[0]的地址
  • &a:数组的首地址,值和a相同
  • a + 1:addr(a[0]) + sizeof(int)
  • &a + 1:addr(a[0]) + 5*sizeof(int)

指针和数组的对比

指针数组
指针变量p保存数据的地址,至于p的本身的地址不关心保存同类型的数据,数组名a表示数组首元素的首地址
间接访问数据直接访问数据
通常用于动态数据结构用于存储固定数据且数据类型相同的元素
相关函数为malloc和free隐式分配和删除

3.4 指针数组和数组指针

  • 指针数组:一个数组,元素都为指针

        int *p1[10]:优先构成数组定义[ ] 优先级高于 *

  • 数组指针:指向数组的指针

        int (*p2)[10]:优先构成指针定义()优先级最高

        数组指针原型:int (*)[10] p,其中指针类型是int (*)[10],p为指针变量

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

alwaysonlinee

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

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

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

打赏作者

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

抵扣说明:

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

余额充值