C++
1. map 结构
1. 判断map结构中一个key是否存在时,一定只能用count函数,只要涉及到map[key]的键值的访问(比如说判断map[key] > 3),即使这个键值事先不存在,也会在执行这条语句时加入到map中,导致map中元素的无限循环。
2. 数组、一维指针、二维指针
1. sizeof() 函数
虽说数组名本质上可以当作地址来看,但是作为 sizeof() 函数参数时存在差异。用数组名作为 sizeof() 参数时,返回的是整个数组在内存中所占空间的大小(字节数),通过字节数就可以得知数组的大小。但是用指针作为 sizeof() 参数时,返回的始终是指针本身所占空间的大小,由机器寻址位数决定,64位机的指针大小为8字节。如下:
int test[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; cout << sizeof(test) <<endl; //结果输出为36,为9个int元素所占总字节数 cout << sizeof(test[0]) << endl; //结果输出为12,为对应一维数组的总大小 int *a = test[0]; //test[0]的类型为int[3],可以直接作为地址赋值 int **b = &a; //二维指针的赋值不能直接用二维数组名test cout << sizeof(a) << endl; //结果输出为8,为指针本身所占空间 cout << sizeof(b) <<endl; //结果输出为8,为指针本身所占空间
2. 指针的初始化以及遍历
在 C++ 中数组的大小必须是一个常量,在初始化的时候就确定了。但是指针所指向的有效空间却不一定,通过指针数组可以将不同长度的一维数组组合成为数组。如下:
int a[]={12,12,34,5}; int b[]={13,17}; int c[]={123,56,4}; int* test[3]={a,b,c}; //test为一个一维指针数组,包含三个整型指针,由于三个指针指向的有效区域长度不同,就构成了纵坐标维度不同的数组 cout << test[1][1] << endl; //输出b[1] = 17 cout << test[2][2] << endl; //输出c[2] = 4
使用指针名带[]的方式,或者*(p+1)的方式的前提条件一定是指针所指向的元素是存在于数组中的(一维数组就是指向数,二维数组就是指向一维指针),所以 p+1 才能自动做相应空间大小的位置跳转。否则 p+1 的结果会得到随机值,并且访问不到相应空间中的值。
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; cout<<a+1<<endl; cout<<&a[1]<<endl; cout<<a[1]<<endl; cout<<*(a+1)<<endl; cout<<&a[1][0]<<endl;
这五句输出的结果值是一样的,都是地址值,但是表示的含义不一样。
所以我总结的二维数组一些性质:
a+1表示行地址 而前面加了个*号就表示列地址了 如*(a+1)。
a[1]表示列地址,前面加个&号就表示行地址了,如&a[1].
&a[1][0]表示列地址,注意当* & [] 这三个符号组合出现的次数为偶数次的话就表示真正的内容值,出现奇数次就表示该内容的地址。
但是请注意& 和()不能组合到一起,所以&(a+1)是错误的。
行地址前加*就表示列地址了,列地址前加*号就表示取内容值,而列地址前加&表示行地址了。所以只有行地址前加*号才能变列地址,加&报错,而列地址前加&变行地址,加*就取得值了,所以对二维数组来说只有列地址前加*号,才能得到内容。如果是行地址,这先要转化为列地址,才能得内容。而行地址套上[]符号就变成列地址了。如a->行地址 a[0]->列地址.总之一点只有当成为列地址后再在前面加*才能取到真正的内容.