1. 关于const用法
- const int a 和 int const a是一样的
- const int *a 意味着a是指向一个常整型数的指针(也就是说整型数是不可修改的,但是指针可以)
- int *const a 意思是a是一个指向整型数的常指针(也就是说指针指向的整型数是可以修改的,但是指针是不可以修改的)
- int const *a const 意思是a是一个指向常整数的常指针(也就是说整数和指针都不可一修改)
2. 一些容易混淆的定义
- 一个整型数 int a
- 一个指向整型数的指针 int *a
- 一个指向指针的指针,他指向的指针是一个整型数 int **a
- 一个有十个整型数的数组 int a[10]
- 一个有十个指针的数组,该指针是一个指向整型数的 int *a[10]
- 一个指向十个整型数数组的指针 int (*a)[10]
- 一个指向函数的指针,该函数有一个整型参数并返回一个整型数 int (*a)(int)
- 一个有十个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型 int (*a[10])(int)
3. 关键字static的作用
- 在函数体内,一个被申明为static的变量在该函数被调用过程中保持其值不变
- 在模块内(函数体外),一个被申明为static的变量可以被模块内的函数访问,但不能被模块外的函数访问。他是一个本地的全局变量。
- 在模块内,一个被申明为static的函数只可以被被这一模块内的函数调用。就是说这个函数被限制在这个模块内部本地使用。
4. 关于关键字volatile(部分摘自百度百科)
- volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.
- 一个定义为volatile的变量就是说这个变量可能会被意想不到的改变,这样,编译器就不会去随便假设这个变量的值了。精确的说,优化器在用到这个变量的值的时候,必须每次都小心的重新读取这个变量的值,而不是使用保存在寄存器里面的备份。
- 下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
1). 一个参数既可以是const还可以是volatile吗?解释为什么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数被用来计算某个整数的平方,它能实现预期设计目标吗?如果不能,试回答存在什么问题:
- int square(volatile int *ptr)
- {
- return *ptr * *ptr;
- }
1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2). 是的。尽管这并不很常见。一个例子是当一个中断服务子程序修改一个指向一个buffer的指针时。
3). 这段代码是个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
- int square(volatile int *ptr)
- {
- int a,b;
- a = *ptr;
- b = *ptr;
- return a * b;
- }
由于*ptr的值可能在两次取值语句之间发生改变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
- long square(volatile int *ptr)
- {
- int a;
- a = *ptr;
- return a * a;
- }
5.一个常用的位操作
- 给一个整型数a,写两段代码,第一个设置a的bit 3,另一个清除a的bit 3
#define BIT3 (0x1<<3)
static int a;
void set_bit3(void ){
a |= BIT3;
}
void clear_bit3(void){
a &= ~BIT3;
}
6.修改内存某处的值
- 要求设置一内存绝对地址为0x67a9的值为0xaa66
- int *ptr;
- ptr = (int *)0x67a9;
- *ptr = 0xaa66;