1.1面向过程
1.1.1 为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。
#pragma once这个也可以
1.1.2 用#i nclude<>引用标准库的头文件,用#i nclude””引用非标准库的头文件,区别是一个从标准库目录开始搜索一个从用户工作目录开始搜索。
1.1.3 与零值比较
不可将布尔变量直接与TRUE,FALSE,0,1直接比较 if( flag ) 或者if( !flag );
整形变量用 = = !=与0直接比较
浮点变量与0值比较 if( x>= -EPSION && x<= EPSION )
指针变量与零值比较用 == !=与NULL直接比较
1.1.5 程序的内存分配与管理
栈区stack,由编译器自动分配释放,存放函数的参数值局部变量的值;
堆区heap,由程序员分配释放;
静态存储区,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的在相邻的另一块区域;
文字常量区,常量字符串就放在这里;
程序代码区,存放函数的二进制代码。
常见的内存错误及其对策:
1) 想用指针传递动态内存,得不到,会使程序崩溃。使用指针的引用或者双指针。
2) 返回指向栈内存的指针,结果不可预料。
3) 释放了内存未置为空,继续使用,指针成为野指针,结果不可预料。
4)内存越界。
5)忘记释放内存,内存泄露。
假设某C工程包含a.c和b.c两个文件,在a.c中定义了一个全局变量foo,在b.c中想访问这个变量该怎么做?
extern type foo;
局部变量能否和全局变量重名?
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量,要用全局变量,需要使用"::"
如何引用一个已经定义过的全局变量?
可以用引用头文件的方式,如果用引用头文件方式来引用某个在头文件中声明或者定义的全局变理,假定你将那个变写错了,那么在编译期间会报错,
也可以用extern关键字,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
可以在两个Cpp文件中定义同名的static变量,static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块,他们都放在数据区,但是编译器对他们的命名是不同的,如果要使变量在其他模块也有意义的话,需要使用extern关键字。
1.1.6 sizeof与strlen
32位机下 int 4位,double 8位,float4位,short2位
指针4位
数组,数组大小,只能测出静态数组的大小,数组作为参数传进函数退化为指针是算不出数组的大小的。
结构对齐三条原则
a. 数据成员对齐规则,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。
b. 结构体作为成员,如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素的整数倍地址开始存储
c. 结构体的总大小必须是内部最大成员的整数倍
空类的大小是1
类中有静态变量,不计算在内。
Strlen是计算字符数组的大小的函数而sizeof是算符
1.1.7 new与delete
New和malloc的区别
1.New是C++中的一个操作符而malloc是C中的一个函数2.new不止是分配内存而且会调用类的构造函数同理delete会调用类的析沟函数,而malloc则只会分配内存,不会进行初始化类成员的工作同样free也不会调用析构函数3.内存泄露对于new与malloc都可以检测出来区别在于new可以指名是文件的那一行而maloc没有这些信息4)new和malloc效率比较
对应的new和delete要采用相同的形式。
string *stringarray = new string[100];
delete stringarray;// stringarray指向的100个string对象中的99个不会被正确地摧毁,因为他们的析构函数永远不会被调用。
如果你在用delete时没用括号,delete就会认为指向的是单个对象,否则,它就会认为指向的是一个数组。
规则:如果你调用new时用了[],调用delete时也要用[]。如果调用new时没有用[],那调用delete时也不要用[]。
1.1.8指针与数组
数组与数组的指针
int a[10]={0}
分析:1)*(a+1) 2)int *ptr=(int *)(&a+1);
*(a+1)就是a[1],a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1]
*(ptr-1)就是a[4],&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小
指针数组
一个指针数组是指一个数组中的每个元素都是一个指针
int *p[10];
函数指针、函数的指针参数以及返回指针的函数
int (*p)(int I,int j);
类成员的指针
指针与数组的对比:
修改内容上的区别。内存复制与比较时候,指针与数组是不一样的。在计算内存容量的时候也是不一样的。用运算符sizeof可以计算出数组的容量,指针sizeof的值却是4,当数组作为函数参数进行传递时数组自动退化为同类型的指针。
指针数组和数组指针区别:
指针数组是指一个数组里面是指针,数组指针是指向数组的指针,代表他是指针指向整个数组。指针数组Int* a[10]; int(*a)[10]数组指针
Int(*a)(int)函数指针
指针与内存分配
如果函数的参数是指针,不要指望用该指针去申请动态内存,因为编译器总是要为函数的每个参数制作副本,如果改变指针所指的内容就可以用来作为输出参数,如果只是改变指针的值,则不能作为输出参数。要实现这个功能必须用指针的指针