c语言初阶学习笔记——常见关键字、static的作用、指针入门、初识结构体

常见关键字:

auto表示这个变量是自动的。

后来因为所有的局部变量都是自动变量,所以auto就省略掉了

像char、int、short这种既是类型又是关键字

auto、register、static表示的是一些变量的存储类型,影响变量的存储位置

越往上速度越快,空间就越小,造价越高

数据都是由CPU处理的,数据哪里来呢,早期是从内存里面拿的,处理完再把数据放回内存里面去,如果CPU的处理速度和内存的读写速度比较搭配那还是挺好的,但是随着技术的提升CPU的处理速度越来越快,但是硬件的读写速度没有这么快,这时候就出现问题了,从内存拿个数据,拿了半天才拿到CPU,CPU马上就处理完了,两者效率严重不匹配,这时候就想找一些更快的存储设备,然后CPU直接去寄存器拿数据,当从寄存器拿数据,正在用某一部分的数据的时候,把高速缓存里的数据往寄存器其他位置上挪,把内存中数据往高速缓存上挪,不断把寄存器里的数据进行替换,只要能保证大概率都在寄存器里面把数据都找到,CPU去拿数据都会有,整体的读写速度就提升上来了。从经济成本考虑,又要为了提升计算机整体的处理速度,然后就衍生出来金字塔型的存储结构

既然寄存器的读取速度特别快,那写代码的时候有人就想说把变量,代码啥的全都放到寄存器里面去,这样代码处理速度就快一些。寄存器关键字也只有建议的作用,会不会把变量放进寄存器取决于编译器,编译器会去评估这个变量是不是被大量频繁的使用,如果是可能就会放进寄存器,如果不是可能就不会这样去做,决定权在编译器。当前的编译器很聪明,不用建议它也能帮你判断,然后决定是否放进寄存器

为什么CPU要的数据总是在寄存器就能拿到呢?这是因为不断把它未来即将可能需要的数据从高速缓存往寄存器拿,从内存往高速缓存去拿,只要空间空出来不用了就替换新的数据进去。这里有一个局部性原理:CPU访问 存储器 时,无论是存取指令还是存取数据,所访问的 存储单元 都趋于聚集在一个较小的连续区域中。 时间局部性(Temporal Locality):如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。

//有兴趣可以看《深入理解计算机系统》

对于typedef是类型重定义,把int*起了个别名int_ptr, int_ptr是一个完整的类型(指针类型)不是替换的,所以用int_ptr定义的c,d都是指针类型的

#define是完成替换的,INT_PTR被替换成int*,int*p1,p2 这样的话只有p1是指针,p1指针指向整形,*给了p1,p2就只能是int类型,要定义应该是int*p1,*p2

static的作用:

1.修饰局部变量(变量的存储位置发生了变化(最本质原因),从而影响变量的生命周期,作用域不受影响)

2.修饰全局变量(static修饰全局变量影响了作用域,本质上修改的是它的链接属性)

3.修饰函数(static修饰函数最终也相当于影响了作用域,本质上修改的是它的链接属性)

1.修饰局部变量:

打印结果是2 2 2 2 2 2 2 2 2 2

static修饰a,出了作用域之后a没有销毁,下次进去的时候a还在,在就不用再创建a了,通过调试可以看到static int a=1没有执行,被跳过去了。static修饰的a还是可以被修改的,只不过不会被重复创建

静态区中的变量是整个程序结束才销毁

static修饰的变量的存储位置发生了变化,从而影响变量的生命周期

最本质的原因是变量的存储位置发生了变化

作用域不受影响,局部变量的a只能在函数内部使用,跟static没关系,加不加static这个a都只能在函数内部使用

2.修饰全局变量:

static修饰全局变量影响了作用域,本质上修改的是它的链接属性

3.修饰函数:

static修饰函数最终也相当于影响了作用域,本质上修改的是它的链接属性

外部函数不声明去调用编译器会警告却可以运行,这是编译器细节处理的问题了,不声明这种写法本身就是存在问题,有的编译器理你,有的就不理你,直接报错了

#define定义常量和宏:

指针:

要谈指针,先理解内存

如果一个内存单元是一个bit,力度太细了,因为在创建变量的时候最小也是个char,如果是这样的话,一个char类型就要分配八个内存单元.

如果一个内存单元是char,就刚刚好一个char类型就给一个地址

每根电线通电

第一根地址线过来的信号是0/1,每根地址线过来的信号也要么是1要么是0

那32根电信号给过来就是32个全0到32个全1之间的范围,列出来32跟地址线上给出来的二进制序列的所有可能性,总共能产生2的32次方个。

每一个这样的二进制序列就可以做一个内存单元的编号

2的32次方个二进制序列作为2的32次方个地址,就能够管理2的32次方个字节的空间

跟代码结合:

10是一个数值要存到a里面去,假设&a取到的是0x0012ff40,这也是个数值(不过是用十六进制表示),这个数值要存起来也得给它一块空间,就给个pa,pa的类型怎么写呢,应该是int*这样写,当我们看到pa前面是int*的时候,我们把pa叫做指针变量。*靠近int还是靠近pa没有明确规定,我们知道pa的类型是int*,理解的时候这个*代表pa是指针变量

指针变量也是变量,所以我们为它也分配了空间

把a地址取出来是有用的,有朝一日能用这个地址找到a所在位置,*pa就是通过这个地址找到a,*pa=20;就是a被覆盖成20。*是解引用操作符

先明白指针变量的作用是存放地址

double是八个字节,但在32位平台下存放你的地址也就需要四个字节而已

sizeof返回值是size_t,想要消除警告可以用%zd接收

结构体:

可以用结构体变量.成员去访问成员,也可以用结构体指针->成员去访问成员

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值