1.static
1.1 static修饰局部变量
关键字static表示的是静态的意思,首先呢,我们先来讲一下static修饰局部变量的作用。下面我们来看一下这段代码。
//static 修饰局部变量
void test()
{
int n = 1;
n++;
printf("%d ", n);
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
我们可以思考一下,这段代码的输出结果会是什么呢?由i=0和i<10可知我们需要调用十次test函数,而值得注意的是局部变量n一旦出了作用域后就会被销毁,我们在每次调用test函数的时候都会重新创建一个局部变量n,也就是说n的值每次开始都是1,然后再进行n++再打印出来,到这,我们应该可以知道结果会是打印出10个2。我们来运行看一下:
由结果可知,我们可以知道test函数中的 n(局部变量)在下一次调用函数时并不会使用上一次调用函数时所得到的n++后的数。
那下边我们就用static来修饰局部变量又会是怎样的呢?
//static 修饰局部变量
void test()
{
static int n = 1;
n++;
printf("%d ", n);
}
int main()
{
int i = 0;
while (i < 10)
{
test();
i++;
}
return 0;
}
我们可以知道static修饰局部变量后,每一次调用函数时都是用的是上一次n++后得到的n。这是因为使用static修饰后,原本被存储在内存中的栈区的局部变量会被存储在内存中的静态区,而存储在内存中的静态区的变量出了作用域也不会被销毁,生命周期延长,但作用域不变。
2.2 static修饰全局变量
接着我们来看一下static修饰全局变量。
未使用static修饰时:
我们来看一下运行结果:
结果不出所料就是10。
使用static修饰时:
运行结果:
我们将会看到报错无法运行了。这是为什么呢?
这是由于全局变量具有外部链接属性,使用static修饰后外部链接属性会变成内部链接属性,变成内部链接属性后只能在全局变量所在的源程序中使用,而不能够被外部解析。
3.3 static修饰函数
我们调用一下外部的函数试试水:
运行结果:
可以看到程序是能够正常运行的,那下边我们来试试用static修饰过后又会是怎样的呢?
运行结果:
可以看到出现了和用static修饰全局变量时类似的问题,无法解析外部命令。
这是由于函数和全局变量类似也具有外部链接属性,static修饰后会变成内部链接属性,只能在本源程序中使用。
1.4 小结
栈区中的变量出了作用域后就会被销毁,而静态区中变量不会被销毁,生命周期是整个程序。
2.指针
我们先来看一下这个简单程序:
#include<stdio.h>
int main()
{
int a = 10;//在内存中开辟四个字节大小的内存,把10存进去
return 0;
}
我们可以来看一下a在内存中的地址:
字节是内存的基本单位,地址以十六进制显示,一个字节代表着一个地址,而指针就是地址。指针变量(p)就是在内存中另外开辟一块空间用来存放地址的,这块空间的大小由机器本身决定。
32位机器–支持32位虚拟地址空间–产生的地址就是32bit位–需要32bit的空间存储4bytes-指针变量的大小是4bytes;
64位机器–支持64位虚拟地址空间–产生的地址就是64bit位–需要64bit的空间存储8bytes-指针变量的大小是8bytes(1个字节是8个比特位,地址的比特位数除以8就是指针变量的大小,与指针变量执行的对象的类型无关)
#include<stdio.h>
int main()
{
int a = 10;//在内存中开辟四个字节大小的内存,把10存进去
int* p = &a;
//1 int表示p执行的的对象是int类型的;
//2 *说明p是指针变量;
//3 &a把a的地址赋给p;
// p成为指针变量
//*解引用操作符
//可以这样进行赋值:*p = 20; a的值就变为了20
return 0;
}
可以看到指针变量p的值就是a的地址。
上图中就可以看到指针变量pc指向ch,通过指针的方式 *pc = 'b' 把字符b赋给ch。
指针图解:
指针变量里存储着a的首地址,有了a的首地址就可以找到a的地址,可以找到a中存储的值。
指针小结:
1. 内存会被划分为小的内存单元,一个内存单元的大小是1个字节
2. 每个内存单元都有编号,这个编号也被称为:地址/指针
3. 地址/指针就可以存放在一个变量中,这个变量被称谓指针变量
4. 通过指针变量中存储的地址,就能找到指针指向的空间