常用类型名称篇
知识点1:
- auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。
auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
1.static的用途。
特点: static局部变量的”记忆性”与生存期的”全局性”
对于函数来说,具有隐藏功能,也就是该函数只针对当前声明的源文件有效,也就不会被其他文件访问和修改,同时如果其他文件中存在相同名称,不会引起冲突,移植性更强
保存变量内容的持久性,我们知道存储在静态区的变量有全局变量和static变量,静态区在程序运行时完成吃时候
默认初始化为0,我们可以将一个变量声明为static,特别是比较大的变量时,这样可以减少程序运行中的工作量
当static修饰的是局部变量时,则改变了就不是存在栈中了,而是在静态区,且当局部变量在离开作用域后,变量并没被释放,任然驻留在内存中,直到程序结束;可以设置变量的存储域
统计计数功能:声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。
- const只会一个修饰符,被修饰的对象将意味着“只读”,const修饰的可以是变量,但不意味着常量, const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效(如:const char a == char const *a != char const a)
const int a;
int const a; //以上表示都是一样的,表示整形数a只读,一般在设置一个数为const时都要初始化,因为后面就没机会了
const int *a; //const修饰的是一个整形指针,所以其指向的值不能改变
int * const a; //const修饰的是指针a本身的地址,所以指针a不能修改,也就是不能改变a中的值
int const * a const; //const及修饰整形指针也修饰指针本身
作用:
* 防止一个变量被修改,在声明时记得初始化值
* 可以设置指针本身为只读属性,也可以设置指针所指向的值只读属性
* 在函数声明中,修饰形参,表示它是一个输入形参,在函数内不可被修改
* 在C++中,修饰成员函数,使其为常函数,不能被修改
* 对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);
operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。
* 节省空间,避免不必要的内存分配
* 提高效率,编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
3.使用的extern “C”和extern “C++”的意义。
由于C和C++之间存在差异,由于C++具有多态性,也就是相同的函数名可以完成不同的功能,CPP 通常是通过参数区分具体调用的是哪一个函数。在编译的时候,CPP 编译器会将参数类型和函数名连接在一起,于是在程序编译成为目标文件以后,CPP 编译器可以直接根据目标文件中的符号名将多个目标文件连接成一个目标文件或者可执行文件。但是在C 语言中,由于完全没有多态性的概念,C 编译器在编译时除了会在函数名前面添加一个下划线之外,什么也不会做(至少很多编译器都是这样干的)。由于这种的原因,当采用CPP 与C 混合编程的时候,就可能会出问题。假设在某一个头文件中定义了这样一个函数:
int foo(int a, int b);
而这个函数的实现位于一个.c 文件中,同时,在.cpp 文件中调用了这个函数。那么,当CPP编译器编译这个函数的时候,就有可能会把这个函数名改成_fooii ,这里的ii 表示函数的第一参数和第二参数都是整型。而C 编译器却有可能将这个函数名编译成_foo 。也就是说,在CPP 编译器得到的目标文件中,foo() 函数是由_fooii 符号来引用的,而在C 编译器生成的目标文件中,foo() 函数是由_foo指代的。但连接器工作的时候,它可不管上层采用的是什么语言,它只认目标文件中的符号。于是,连接器将会发现在.cpp 中调用了foo() 函数,但是在其它的目标文件中却找不到_fooii 这个符号,于是提示连接过程出错。extern “C” {} 这种语法形式就是用来解决这个问题的。本文将以示例对这个问题进行说明。
注意:用g++编译cpp程序时,编译器会定义宏 __cplusplus ,可根据__cplusplus是否定义决定是否需要extern “C”。
总结:由于C++与C的在编译时,使用的编译器不同C(gcc),C++(g++),所以编译的协议可以有所不同,所以如果C++在编译C的接口时,不是按照C编译器的规则的话,则到时候在连接器中就无法连接,很好的例子就是C++使用C写的dll时,所以可以说是解决C和C++的兼容
总结:extern “C”使用来混合使用C/C++编程时用来解决C/C++的兼容性的,进一步说就是告诉连接器在目标文件中寻找对应接口时,以C还是C++的方式来寻找和连接
4.extern和export的意义。
extern:在定义函数时,如果在函数首部的最左端冠以关键字extern,
则表示此函数是外部函数,可供其它文件调用。C语言规定,如果在定义函数时省略extern,则隐含为外部函数。export:export关键字只有在使用局部编译模式时才会用到,同时需要编译器支持局部编译模式,如果编译器不支持这种编译模式,那么不能使用export
5.头文件中的ifndef/define/endif干什么用?
ifndef和endif是一条条件预编译宏,ifndef表示如果没有定义特定宏,则执行,如果定义了该特定宏则不执行
endif用来结束条件预编译宏
define用来声明一个预编译宏
6.#include<>和#include”“的区别
在寻找包含的头文件时,搜索的环境域不一样
<>:环境域不仅仅包含源文件目录,同时也包含用户设置的环境
“”:则只包含源文件目录