一、关键字
1.变量的声明和定义有什么区别?
1)为变量分配地址和存储空间的称为定义,不分配内存空间的称为声明。
2)一个变量可以在多个地方声明,但是只在一个地方定义。
3) 加入extem修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。
*说明:很多时候一个变量,只是声明不分配内存空间,直到具体使用时才初始化,分配内存空间,如外部变量。
2. sizeof 和 strlen 的区别
1)sizeof 是一个操作符(关键字),strlen是库函数。
2)sizeof 的参数可以是数据的类型,也可以是变量,而 strlen 只能以结尾为 ‘/0’的字符串做参数。
3) 编译器在编译时就计算出了sizeof的结果。而strlen函数必须在运行时才能计算出来。
4)sizeof 计算的是数据占内存的大小,strlen 计算的是字符串实际的长度(不包含结束符‘\0’)。
5)数组名用做 sizeof 的参数不退化,传递给 strlen就退化为指针了。
3. static关键字的作用,以及static在C语言中与在C++中的区别?
1)作用:
1、修饰全局变量
改变变量的作用域,让它只能在本文件中使用。所以多个源文件可以定义同名的static全局变量,不会产生重定义错误。
2、修饰局部变量
变量只初始化一次,生存期为整个源程序,程序结束,它的内存才释放。但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
它放在.data 或者.bss段,默认初始化为0。初始化不为0放在.data段,没有初始化或初始化为0放在.bss段。程序一运行起来就给他分配内存,并进行初始化,也是唯一一次初始化。它修饰局部变量是改变它的生存期,变为和整个程序的生命周期一样。
3、修饰函数
和修饰全局变量一样,只在本文件中可见(即只能在本文件中被其他的函数调用)。
4、修饰类的成员变量
就变成静态成员变量,不属于对象,而属于类。不能在类的内部初始化,类中只能声明,定义需要在类外。类外定义时,不用加static关键字,只需要表明类的作用域。
5、修饰类的成员函数
变成静态成员函数,不属于对象,只属于类。形参不会生成 this 指针,仅能访问类的静态数据和静态成员函数。调用不依赖对象,所以不能作为虚函数。用类的作用域调用。
2)区别:
在C中 static 用来修饰局部静态变量、全局静态变量和函数。而C++中除了上述功能外,还用来定义类的成员变量和函数。即静态成员和静态成员函数。
注意:编程时 static 的记忆性,和全局性的特点可以让在不同时期调用的函数进行通信,传递信息,而C++的静态成员则可以在多个对象实例间进行通信,传递信息。
4. const 关键字的用途和作用
(1)可以定义 const 常量
(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被const 修饰的东
西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
1)防止被修饰的成员的内容被改变。
2)修饰类的成员函数时,表示其为一个常函数,意味着成员函数将不能修改类成员变量的值。
3)在函数声明时修饰参数,表示在函数访问时参数(包括指针和实参)的值不会发生变化。
4)对于指针而言,可以指定指针本身为const,也可以指定指针所指的数据为const,const int *b = &a;或者int* const b = &a;修饰的都是后面的值,分别代表*b和b不能改变 。
5)const 可以替代c语言中的#define 宏定义,好处是在log中可以打印出BUFFER_SIZE 的值,而宏定义的则是不能。
#define BUFFER_SIZE 512
const int BUFFER_SIZE = 512;
*注意:const数据成员必须使用成员初始化列表进行初始化。
5. extern关键字的作用
extern 标识的变量或者函数声明其定义在别的文件中,提示编译器遇到此变量和函数时在其它模块中寻找其定义。(只声明不定义)
6. volatile 关键字的作用及使用场景
1)作用:
volatile修饰的变量在使用的时候不会直接在寄存器中取值,而是从内存中取值。
volatile的本意是“易变的” 因为访问寄存器要比访问内存单元快的多,所以编译器一般都会做减少存取内存的优化,但有可能会读脏数据。当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。精确地说就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
2)使用场景:
a)中断服务程序中修改的供其它程序检测的变量需要加volatile【一个中断服务子程序中会访问到的非自动变量】
b)多任务环境下各任务间共享的标志应该加volatile【多线程应用中被几个任务共享的变量】
c)存储器映射的硬件寄存器通常也要加voliate,因为每次对它的读写都可能有不同意义。【并行设备的硬件寄存器】
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2)一个指针可以是volatile吗?解释为什么。
3)下面的函数有什么错误:
int square(volatile int*ptr){
return*ptr**ptr;
}
下面是答案:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2)是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3)这段代码有点变态。这段代码的目的是用来返指针*pr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{ int a,b; a = *ptr; b = *ptr; return a * b; }
由于*ptr的值可能被意想不