第一篇 C++编程常用技术

C++易混淆点

1.关于头文件的包含

  • #include <> 常用来包含系统提供的头文件,编译器会到保存系统标准头文件的位置查找头文件
  • #include “” 常用于报货程序员自己编好的头文件,用这种格式时,编译器先查找当期目录是否有指定的头文件,然后从标准头文件中进行查找。

2.函数重载

  • 定义:使用同一个函数名定义多个函数,但这些函数必须参数个数不同类型不同
  • 注意点:在使用函数重载时,同名函数的功能应当相同或相近,不要用同一函数名去实现几个完全不相干的功能,这样虽然程序能运行,但是可读性不好,会让人觉得莫名其妙。

3.函数模板

  • 格式:template
  • 实例:
#include 
using namespace std;
template
T min(T a, T b, T c){
   if(a>b) a=b;
   if(a>c) a=c;
   return a;
}
int main(){
   int a = 1, b = 2, c = 3;
   cout << min(a, b, c)<

4.strlen()与 sizeof()的区别

  • strlen()是函数,在运行时才能计算,参数必须是字符型指针(char *),且必须是一’\0’结尾的。当数组名作为参数传入时,实际上数组已经退化为指针了。它的功能是返回字符串的长度。
  • sizeof()是运算符,而不是一个函数,在编译时就计算好了,用于计算数据空间的字节数。因此sizeof不能用来返回动态分配的内存空间的大小。sizeof常用于返回类型和静态分配的对象、结构和数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。

5.指针

5.1数组与指针

  1. 数组指针,也称为行指针
    格式:int (*p)[n]
    分析:()优先级高,说明p是一个指针,且指向一个整型的一维数组。这里p的步长为n个整型数据的长度。

  2. 指针数组
    格式:int *p[n]
    分析:[]的优先级高,可以理解为先与p结合成一个一维数组,再由int *说明这是一个整型指针数组,它有n个指针类型的数组元素。

  3. 区别
    *数组指针是一个指针变量,可以认为是C语音里专门用来指向二维数组的,他占用内存中一个指针的存储空间;
    *指针数组是多个指针变量,以数组形式存在内存中,占用多个指针的存储空间。

  4. 相同点
    同时用来指向二维数组时,其直接引用和用数组名引用都是一样的。

优先级:()>[]>*

5.2字符串和指针

  1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。可以改变变量使它指向不同的字符串,但不能改变变量所指的字符串常量。(eg: char *p = “hello world!”)因为定义指针时,编译器并不为指针所指向的对象分配内存空间,它只是分配指针本身的空间,所以hello world会被当成常量,并且被放到程序的常量区,不能被修改;
  2. 字符串本身是存放在以该首地址为首的一块连续的内存空间中,并以‘\0’作为字符串的结束标志;
  3. 字符数组是由若干个数组元素组成,每个元素中存放字符串的一个字符。定义一个字符数组,编译后就会分配一个内存单元,每个元素都有确定的地址。

5.3函数指针与引用

  1. 函数指针的声明方法
    返回值类型 (* 指针变量名)([形参列表])
  2. 引用的注意事项
    在声明一个引用变量时,必须同时使之初始化,即声明它代表哪个变量。函数执行期间,不可以将其再作为其他变量的引用。

引用比指针作为参数时更有效率。
在const int &r=a;这类型的常引用中,用引用变量更改数据,可以使用a变量进行数据的更改。

6.结构体、共用体、枚举、宏

#include 
using namespace std;

typedef union{
	long i;
	int k[5];
	char c;
}UDATE;

struct data{
	int cat;
	UDATE cow;
	double dog;
}too;

enum e_weekday{
	sun,
	mou,
	tue,
	wed,
	thu,
	fri,
	sat
};

struct STR{
	char i;
   	int j;
    	short k;
    	double m;
    	int n;

};

int main(){
	cout << "sizeof(short) = " << sizeof(short) << endl;
	cout << "sizeof(STR) = " << sizeof(STR) << endl;
	cout << "sizeof(char) = " << sizeof(char) << endl;
	cout << "sizeof(float) = " << sizeof(float) << endl;
	cout << "sizeof(long long) = " << sizeof(long long) << endl;
	cout << "sizeof(int *) = " << sizeof(int *) << endl;
	cout << "sizeof(e_weekday) = " << sizeof(e_weekday) << endl;
	cout << "sizeof(char *) = " << sizeof(char *) << endl;
	cout << "sizeof(doule) = " << sizeof(double) << endl;
	cout << "sizeof(long) = " << sizeof(long) << endl;
	cout << "sizeof(int) = " << sizeof(int) << endl;
	cout << "sizeof(UDATE) = " << sizeof(UDATE) << endl;
	cout << "sizeof(too) = " << sizeof(too) << endl;
	return 0;
}

在64位机器上的输出结果,其中long类型在32位机器上只占4Byte
sizeof(short) = 2
sizeof(STR) = 32
sizeof(char) = 1
sizeof(float) = 4
sizeof(long long) = 8
sizeof(int *) = 8
sizeof(e_weekday) = 4
sizeof(char *) = 8
sizeof(doule) = 8
sizeof(long) = 8
sizeof(int) = 4
sizeof(UDATE) = 24
sizeof(too) = 40

结构体成员是有一种默认的对齐的方式的:在本例中,结构体中的char,int,short为与double对齐,所以必须要凑够8个字节,char 与int对齐,各占4字节凑够了8字节,char,int占了8个字节,为对齐所以short也占了8字节,下面int和char也凑够了8字节,所以共占了32个字节

注意事项:

  • 可以使用union判断系统是big endian(大端)还是little endial(小端)
    其中大端是指低地址存放最高有效字节,小端则是指低地址存放最低有效字节

  • 几乎所有的网络协议都采用big endian的方式来传输数据,在两台采用不同字节序的主机通信时,在发送数据之前都必须转换为网络字节序(big endian)后再进行传播。
    将0x1234abcd写入0x0000开始的内存,结果如下表

地址 big endian little endian
0x0000 0x12 0xcd
0x0001 0x34 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
  • 同一枚举类型中的枚举子的取值不需要是唯一的,可以相同
  • union中变量公用内存,因以最长的为准,公用体内变量的默认对齐方式,必须以最长的对齐
  • 宏定义中要遵循先替换后计算的原则,因此带参数宏定义,要给宏体中的每个参数加上括号,并在整个宏体上再加一个括号
  • 定义宏时建议使用do{…}while()的格式,可以使得宏扩展后,仍然保留初始语义,保证程序的正确性。

你可能感兴趣的:(C++后台开发)