近几天在到处找工作,跑各大宣讲会、校园招聘会。也经过了几次笔试,现将笔试过程当中的一些疑惑整理整理。
static的用法
经过多方查询,我将static的用法归为三条
1.最重要的一个用法:隐藏
static会限制变量或函数的“可见性”,使变量和函数只在本文件中是可见的,而外部文件无法访问。举例说明下,假设有两个文件,分别是a.c,main.c。
以下为a.c的内容
char a = 'C'; //global variable
void fun()
{
printf("Hello\n");
}
以下为main.c的内容
int main()
{
extern char a; //extern variable
fun();
printf("%c ",a);
return 0;
}
程序运行结果为:Hello C
而如果在a.c中这样定义
static char a = "C";
static void fun()
{
printf("Hello\n");
}
则在main.c中就无法调用a和fun()了。以上程序就会报错了。
利用这一特性可以在不同的文件中定义同名变量和同名函数,而不比担心命名冲突。
2.使变量的寿命悠长
一般变量存储在栈中,要用时分配一块空间,用完后就回收了。而static使变量存储在静态数据区,在程序刚运行时就完成初始化,分配一块空间,一直到程序运行结束。这和全局变量是一样的,所以说static最主要的作用还是隐藏。
利用这一特性可以用来计数,比如记录某一函数被调用了多少次。在我们单片机编程当中,可以设置flag等。
3.默认初始化为0
在静态数据区,内存中所有的字节默认值都是0x00。所以static会默认初始化为0,和全局变量一样。
指针数组和数组指针
指针数组:以数组为中心词,即用于存储指针的数组,其本质为数组,而数组的元素为指针。
数组指针:以指针为中心词,即指向数组的指针,其本质为指针,只是指向一个数组。
它们的定义如下:
int* a[2]; //指针数组
int (*a)[2]; //数组指针
它们的用法如下:
#include <stdio.h>
int main()
{
int c[2]={1,2};
int* a[2]; //指针数组
int (*b)[2]; //数组指针
b = &c; //数组指针b指向数组c
//将数组c中的元素赋给数组a
for(int i = 0; i < 2; i++)
{
a[i] = &c[i];
}
//输出,看结果如何
printf("*a[0] = %d\n",*a[0]); //应输出为1
printf("(*b)[1] = %d\n",(*b)[1]); //应输出2
}
指针函数和函数指针
指针函数:其本质是一个函数,只是函数的返回值为指针类型。
函数指针:其本质为一个指针,但这个指针指向一个函数。
它们的定义如下:
int* f(int a ,int b); //指针函数
int (*f)(int a ,int b); //函数指针
指针常量和常量指针
指针常量:以常量为中心词,其本质为常量,不过是指针类型的常量。简单点说就是这个指针指向一个固定的地址,不可改变,但这个地址中存储的值是可以改变的。
常量指针:以指针为中心词,其本质为一个指针,但这个指针指向一个常量。也就是说,它指向的值不可改变,但这个指针可以改变。
举例说明:
//指针常量
int* const b = &a;
*b = 2; //合法的
b = &c; //非法的
//常量指针
const int* b = &a;
*b = 2; //非法的
b = &c; //合法的
另外说一个指向常量的指针常量
顾名思义,它是一个常量,且它指向的对象也是一个常量。
定义为:const int* const b = &a;
小结:
可以看到以上三组关于指针的辨识比较绕,仔细一看,其重点也就是中心词其实都在后面。其实说来,这些名词看英文会比较清晰明了,比如:
指针数组:array of points
数组指针:a point to an array