static和const小笔记

[TOC]

static和const是C语言的定义修饰符, 这个在之前的笔试面试的时候就都碰到了, 这里还是要好好的总结下, 避免悲剧.

static

static有两个特性:

  1. 修饰的对象会被放在全局存储区;
  2. 修饰的对象的非全局作用域.

简简单单两个特性, 但是理解起来还是有难度的. 第一个特性是值针对变量对象(包括结构体)不针对函数对象的, 指的是static变量是的存储区是全局存储区; 而非全局作用域说的是变量和函数, 指的是static修饰的对象不能是全局对象.

还是来几个示例来具体说说吧:

1
2
3
4
5
6
7
int foo(void)
{
static int bar = 0;
int tmp;
bar++;
return bar;
}

这个函数里面变量bar就是static变量, 存储区是在全局存储区, 而另外的变量tmp是普通的局部变量, 存储区是在堆栈区. 每次调用foo()这个函数, 会返回每次加1的返回值:

1
2
3
4
5
6
7
8
int main(void)
{
int ret;
ret = foo(); //set ret to 1
ret = foo(); //set ret to 2
ret = foo(); //set ret to 3
}

这里的会引出另外一个知识点, 就是可重入这个概念. 对一个模块相同的输出就有相同的输出, 这个就叫可重入, 所以foo()这个函数是不可重入的.

然后就是非全局作用域这个属性, 这个说的static对象是不能用作全局对象的, 只能在当前文件里面使用. 一个变量要想真正成为一个全局变量, 除了在函数体之外定义, 还有一步就是需要在头文件里面声明, 然后在需要用到这个变量的文件里面都要包含这个头文件. static就是隔离了这个操作, 也在头文件里面做声明然后在另外的文件里面使用这个变量的时候就会报错. 这么一说的话这个属性就是用来防止错误引用的, 并没有什么功能性的用途.

const

const都是用来修饰对象, 但是种类就有很多:

类型 描述
变量 const 类型说明符 变量名
引用 const 类型说明符 &引用名
成员函数 类名::fun(形参 const)
数组 类型说明符 const 数组名[大小]
指针 const 类型说明符 指针名; 类型说明符 const 指针名

然后这里除了指针外, const的位置和类型说明符的位置是可以互换的, 就是说const int a = 5;int const a=5;是一样的. 使用指针时涉及到两个对象: 该指针本身和被它所指的对象, 然后const在这里就会有相应的两种意义:

1
2
int *const p1; //a const pointer to int
const int *p2; //a pointer to const int

上面的代码就是说p1是指向int的常量指针, 常量指针指向的值是可变的, 而指针的值(就是地址)是不能变的. p2是指向int常量的指针, 其指向的值不可变而指针的值可变. 这样一说, 像是const int *const p3这样的指针也是存在的, 不过这样的指针是有什么意义呢.