1. const关键字 --- 只读
- const修饰普通变量,使其变为只读变量,不能直接修改内存内的数据
- const int *p3;
- 表示指向的内存不可改变,指针自身可变(可以指向其他地址)
- int const *p3; // 与 const int *p3 等价
- 表示指向的内存不可改变,指针自身可变(可以指向其他地址)
- int *const p3;
- 表示指针自身不可变(不可以指向其他地址), 但是指向的那段内存可修改
- const int * const p3;
- 表示指针自身不可变, 指向的内存也不可变
int a = 100;
a = 200;//正确
const int b = 100;
b = 200;//错误,由const修饰的变量b 为只读变量,不能通过变量名修改其内存空间的数据,但是你可以定义一个指针,去间接修改
例如int *p = &a;
*p = 100; //警告类型不匹配,但是能够强制更改内容
// p1变量指向 const int型的地址, p1变量不是只读变量,但是const不修饰p1
const int *p1 = &a;
*p1 = 100; //报错
p1 = &b; //p1指向b的地址,这是正确的,因为p1不是只读变量
int c = 13,d = 15;
int * const p = &c;
p = &b; //报错, const用来修饰指针变量p,指针变量p变为只读,不可修改
//如果 指针指向const int数据类型的地址,并且想让指针变量自身只读
const int *const p2 = &b;
*p2 = 12; b 是 const int 不可修改
p2 = &a; p2 是 const p2 ,p2自身也不可修改
const int *p3; // 表示指向的内存不可改变,指针自身可变(可以指向其他地址)
int const *p3; // 与 const int *p3 等价
int *const p3; // 表示指针自身不可变(不可以指向其他地址), 但是指向的那段内存可修改
const int * const p3; // 表示指针自身不可变, 指向的内存也不可变
2. volatile关键字
volatile的意思是 “易变的”,应该解释为“直接存取原始内存地址”比较合适。
“易变”是因为外在因素引起的,比如多线程,中断等等。
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。
如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。(简洁的说就是:
volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错)
int main(void)
{
volatile int i;
int j;
i = 1; //1 不被优化
i = 2; //2 不被优化
i = 3; //3 不被优化
j = 1; //4 被优化
j = 2; //5 被优化
j = 3; //6 j = 3
}
//单片机延时函数
void delay()
{
int i = 0x1000000;
while(i--);
}
//单片机延时函数
void delay()
{
volatile int i = 0x1000000; //防止编译器优化变量
while(i--);
}
3. register寄存器变量
调用频繁的变量可以定义成一个寄存器变量
- 定义寄存器变量不一定成功(主要看编译器),如果不成功会自动定义成自动化变量(auto
- 寄存器变量没有内存地址,所以不能取地址 &a
register int a = 10;// 变量在定义的时候会分配寄存器存储
&a 是错误的
总结:变量从存储位置来说一般分为两种:
存储在内存地址的自动化变量和存储在寄存器的寄存器变量。
4. typedef
typedef 用来声明一个新类型
作用:给一个已经定义了的类型取一个新的名字,使新的名字更能表示它的含义。
- 给结构体取别名
typedef struct node{
int data;
}Node_t,*pNode_t;//表示给struct node结构体变量取一个别名Node_t,表示给struct node结构体指针变量取一个别名pNode_t
struct node{
int data;
}Node_t,*pNode_t; //如果没有使用typedef关键字修饰,此时Node_t是该结构体的变量,pNode_t是该结构体的指针变量
- 给数组取新名字
typedef int array[10];//新的类型为array,代表int[10];
array a;//定义一个数组a,它有10个元素,每个元素为int类型。
- 给函数指针取新名字
int (*p)(int,char);//定义一个函数指针变量p
typedef int (*pfunc)(int,char);//声明一个新类型pfunc,该类型与p一样
- 给变量取新名字
// int b, *c; // 声明 int 变量 b 和 int * 变量 c
typedef int b, *c; // 声明 int 类型别名 b, 和 int * 类型别名 c
Comments NOTHING