1.const
概述
定义只读变量的关键字。(不要说常量,很业余)
修饰变量 :被const修饰的变量只有读属性。
修饰函数:在C++中用到,表示在这个成员函数中不会修改数据成员,如果试图修改会报错。
修饰参数:C\C++中都用到,保证传入参数的值在函数体内不被修改,如果试图修改会报错,增加函数的健壮性。
修饰返回值:一般修饰指针的偏多,表示函数的返回值,及指针的内容不能被修改。并且返回值只能赋值给别const修饰的同类型指针。
用例
普通变量:
const int a = 10;
int const a = 10; // 两条语句的效果是一样的
指针变量:
++++++++++++++++++++++++++
const int * pt1 = &a; //表示内存中的值不能修改
*pt1 = 20; //编译错误,
pt1 = & b;
++++++++++++++++++++++++++
int * const pt2 = &a; //表示指针指向的地址不能修改
*pt2 = 20;
pt2 = &b; //编译错误
++++++++++++++++++++++++++
2.static
概述
static关键字用于修饰静态变量。
全局静态变量:
1.内存中存放的位置:静态储存区,在整个程序运行过程中都存在。
2.初始化:没有初始化的静态全局变量,程序会自动初始化为0。
3.作用域:在声名它的文件之外是不可用的,从定义或者声名处到文件结尾。
局部静态变量:
1.内存中的存放位置:静态储存区,在整个程序运行过程中都存在。
2.初始化:没有初始化的全局变量,程序会自动初始化为0。
3.作用域:作用域不变,依旧是定义它的函数或者语句块的结束就结束了。
全局变量和局部变量能重名吗?如果能重名那么作用域会怎么样?
能重名,局部变量的作用域会覆盖全局变量的作用域。类似于就近原则。
补充:static关键字修饰函数
概述
static关键字修饰的函数叫静态函数,静态函数的作用域只在函数所在的文件,失去了全局可见性。编译器只有函数的入口地址,没有函数名。
静态函数的有点:
1.静态函数不能被其他文件调用,增加安全性。
2.其他文件中可以定义同名的函数,不会发生冲突。
3.extern
概述
extern的作用是声名外部变量,全局变量可能定义在使用处之后,或者别的文件中。从声名处起可以合法的使用外部变量。
声名变量和定义变量的区别:
1.定义变量会创建一块内存,而声名不会。
2.变量可以声名多次,但是只能定义一次。
4.sizeof和strlen
1.sizeof是用算符,能计算各种变量所占的内存大小。strlen是函数,只能计算字符串的有效长度,不包括'\0'。
2.sizeof计算内存长度时不会考虑内存里的内容,只考虑长度。
5.malloc和free
概述
malloc申请一块指定大小的堆内存。
free释放指针指向的malloc申请。
注意点:
1.mallco的参数是要申请内存的大小,返回值是一个viod无类型的指针,需要强转后赋值给指针变量。
同类函数:
1.calloc:申请一块内存,然后将每一个字节初始化为0。
pt = (int *)calloc(10, sizeof(int))
2.ralloc:更改已经申请出来的内存。第二个参数为重新申请后的大小。
注意:如果pt后面足够扩展,则会返回pt。如果pt后面不足,那么会寻找一块足够的新内存,把原来内存里的数据拷贝过来。返回新内存的指针。
pt = (int *)ralloc(pt, sizeof(int) *20)
2.malloc函数不一定100%申请成功,调用完要判空。申请出的堆内存不一定干净,所以一点要初始化。
3.free函数只是斩断内存和指针的关系,内存还在,指针还在。指针要赋值为NULL,避免成为野指针。
用例
#include <malloc.h> // 头文件
int *pt = NULL;
pt = (int *)malloc(sizeof(int) * 10);
if(pt == NULL)
{
;//error
}
memset(pt, 0x00, sizeof(int) * 10);
printf("%d\n",sizeof(pt));
printf("%d\n",sizeof(pt) * 10);
free(pt);
pt = NULL;
6.strcpy和memcpy以及sprintf
概述
strcpy
函数原型,返回的是目标字符串的地址。
char *strcpy(char *dest, const char *src);
特点:strcpy只要用于两个字符串之间的拷贝。当源比目标大时会报错。所有要使用安全版本strncpy。注意strcpy和strncpy都是遇到'\0'结束复制,不会复制'\0'。
char *strncpy(char *dest, const char *src, int n);
复制目标字符串的前n个字符。
memcpy
函数的原型,返回的是拷贝目标的地址。
void *memcpy(void *destion, void *source, unsigned n);
特点:从源拷贝n个字节到目标。但是当源和目标有内存重叠时会发生浅拷贝(很少见)。如果有这种风险可以使用memmove,memmove内部做了内存重叠的处理。
sprintf
特点:将所有类型转换为字符串的情况用的多,现在用sprintf_s的安全版本。
char pt1[10];
sprintf_s(pt1, "char:%d", 5);
printf("%s\n", pt1);
printf是将数据转换成字符串以后打印在屏幕上,而sprintf是保存在指定的字符串中。
7.switch的参数和跳出问题
概述
可以作为switch参数的类型有:int, char, bool, short
不能作为switch参数的类型有:float, double
switch从第一个匹配到的分支进入,遇到break才跳出。
8.while和do while的区别
while和do while的区别是,当第一次判断while条件失败时,while执行0次,while执行1次。
9.register
register关键字定义变量,变量存在寄存器中。用于频繁使用的变量可以提高性能。
由于其不放在内存中,所以不能取地址,不能是自定义的变量类型。
静态变量不能用register修饰。