变量相应的存储位置:
程序在编译前都会给每一个变量分配一个相对应的存储空间,而不同的存储空间则会有不同的使用范围,这往往是根据变量的类型而决定。
现在就将存储空间大致分为三个区:栈区、堆区、静态区。
栈区:
在这个区所存储的变量一般是“临时工”,作用范围有限,且生命周期较短。
上述的a,b都是局部变量。除此之外,还有函数参数,这也是临时变量,这种参数只是形式上在调用方法时开辟的新空间接收数据并在方法内使用,一旦调用完方法,照样是“灰飞烟灭”。
堆区:
一般在堆区储存的是动态内存分配的变量,有malloc 、calloc 、relloc 、free等(现在基本没什么了解,也说不出什么东西)。
静态区:
典型的有用 static 修饰的变量,还有全局变量。
放在静态区的数据创建后直到程序结束才释放。
static 修饰变量:
三种用法:
1、修饰局部变量
2、修饰全局变量
3、修饰函数
修饰局部变量:
本质上,static的修饰改变了局部变量的存储位置,将修饰的局部变量放在了静态区。
**但需要注意的是,被 static 修饰的变量的作用域不变!**
修饰全局变量:
全局变量本身的性质:自身可被所处文件引用,也可被其他源文件引用。
原因在于全局变量具有外部链接属的,但在被 static 修饰后,外部链接属性就变成内部链接属性。那么,这个全局变量的作用域就只在自己所在的源文件内部使用(减少工作量,也减少出错的可能)。
修饰函数:
整体和全局变量的情况一样。
宏:
int m = Add(a,b);
//int m = a + b;
//这两种方式是一样的
指针:
有句俗话说得好:“C语言不能失去指针,正如西方不能失去耶路撒冷”(bushi)。有了指针,C语言才能干出许多高精度的东西。而指针是不能脱离内存而独活的。
内存介绍:
内存是计算机上的一种存储空间(8G/16G)。程序运行的时候会载入内存,程序中如果有数据需要存储时也会申请内存空间。
如图所示,内存空间为了方便管理就将存储空间进行分割,变成了一个个小的内存单元,变量的地址就由内存单元进行存储。
那怎么访问内存单元?那就要通过编号实现了。编号是由二进制序列所实现的,对于32位机器而言,其有2的32次方个这样的二进制序列,进而有2的32个字节的内存空间。
简而言之,在32位机器上就是32个bit位,在64位机器上就是64个bit位。
指针大小:
在不同位数的机器上的指针大小不同,在 x86 的机器上的大小为4个字节,在 x64 的机器上是8个字节。每个字节对应8个bit,每4个bit都会对应一个16进制的数字,因此,一个内存编号则由两个16进制数字来表示,不同的平台导致内存编号的个数不同。
这总共有四个字节,表示一个4字节的指针内存,当使用 %p 来打印指针的地址时,它只会打第一个内存地址编号,这里即0x012FFA90.
指针的定义及初始化:
int a = 0;
int* pa = &a;
这里定义了指针变量pa,并将其初始化。初始化是通过 & 取地址操作符将a的地址赋给pa,因此,指针变量是专门用来获得变量的地址,具有指向性。这个操作是将a所占内存的4个字节中的第一个字节的地址赋给pa。
对于指针变量的数据类型,其与指向变量的数据类型保持一致。
指针的解引用操作:
*pa = 20;
这个操作是将pa所指向的变量给找出来,并通过赋值的方式改变变量的值。