数组和指针、数组指针和指针数组、函数指针和指针函数、数组标识符的意义、静态和动态创建的数组的本质区别、标识符类型判断方法
- #include <iostream>
- using namespace std;
- void tArray1(int *p)
- {
- for (int i = 0; i < 3; i++)
- {
- *(p+i) = *(p+i)+1;
- cout << *(p+i) << endl;
- }
- }
- void tArray2(int a[])
- {
- for (int i = 0; i < 3; i++)
- {
- a[i] = a[i] + 1;
- cout << a[i] << endl;
- }
- }
- void tFunc1(void (*f)())
- {
- (*f)();
- }
- void func1()
- {
- cout << "hello world" << endl;
- }
- float *find(float (*ptr)[4],int n)
- {
- float *pt;
- pt = *(ptr + n);
- return (pt);
- }
- void main()
- {
- /**************** 指针和数组的关系***********************/
- //对指针可以直接进行下标检索操作,这时把指针当前空间作为数组首元素进行操作,自己进行越界检查
- //这个时候解引用运算符和下标运算符检索效果是相同的
- /*int a[3] = {1,2,3};
- cout << a <<endl;
- cout << *a << endl;
- cout << a[10] << endl;//需要自己进行越界检查
- //a++;//编译报错,因为数组标识符是一个只读指针不能改变其值,如果要通过指针遍历要通过把它传给其他指针进行
- int *ptr = a;
- cout << ptr << endl;
- cout << ptr[0] << endl;
- cout << ptr[1] << endl;
- cout << *ptr << endl;
- ptr++;
- cout << ptr << endl;
- cout << *ptr << endl;
- cout << ptr[1] << endl;//这个时候把ptr当前位置作为数组的第一个元素
- cout << ptr[10] << endl;//需要自己进行越界检查
- int c = 10;
- int *p = &c;
- cout << p[0] << endl;
- //p[1] = 16; //编译报错,越界访问
- cout << p[1] << endl;//这个时候就是一个不可预知的值了,需要自己进行越界检查,实际就是p的下一个四字节单元存储的值
- cout << endl;*/
- /**************************指针数组和数组指针*********************************/
- /*int arrInt1[3] = {1,2,3};
- int arrInt2[3] = {4,5,6};
- int arrInt3[3] = {7,8,9};
- int *p[3];//根据运算符优先级相当于int *(p[3]);p是一个数组,数组元素存储指针类型,指针是int类型的(指针数组)
- p[0] = arrInt1;
- p[1] = arrInt2;
- p[2] = arrInt3;
- cout << *p[0] << "+++" << *p[1] << "+++" << *p[2] << endl;
- int (*ptr)[3];//这个时候使用()进行了运算符优先级强制限制,ptr是一个指针,指针是int [3]类型的(数组指针,而且十分严格)
- //ptr = arrInt1; //编译报错,因为类型不一致,且编译器不做自动转换
- ptr = &arrInt1;//意义就是取这个数组的首地址,和arrInt1是数值相同的,&arrInt1取得的是一个int [3]类型的指针,即int (*)[3]
- cout << arrInt1 << endl; //取得的是数组的首地址,但是这个时候的类型是int [3]
- cout << ptr << endl;
- cout << ptr[0] << endl;
- cout << *ptr << endl;//取得的是它指向的那个数组的首地址
- cout << *ptr[0] << endl;
- cout << ptr[1] << endl;//实际上是取得下一个int [3]数组的地址
- cout << *(ptr+1) << endl;
- cout << *(ptr[0]+1) << endl;
- int *p1; //虽然arrInt2是int [3]类型的,但是编译器/c++标准允许将其首地址转换为一个int *类型
- //p1 = &arrInt2; //编译报错,编译器不做这种类型自动转换,把
- p1 = arrInt2;
- cout << p1 << endl;
- cout << p1[0] << endl;
- cout << *p1 << endl;*/
- /**********数组做参数,实际上传入的都是指针*************/
- /*int array[3] = {1,2,3};
- int *pArray = array;
- tArray1(pArray);
- tArray2(array);
- for (int j = 0; j<3; j++)
- {
- cout << array[j] << endl;
- }*/
- /********函数指针(指向函数的指针) 和 指针函数(函数返回值是指针)*******************************************/
- //小结:关于一个变量是什么类型的判断要根据运算符优先级和结合性来判断,()、[]优先级高于*,()、[]是从左
- //向右运算,*是从右向左运算。
- //跟变量第一个结合的运算符决定了变量的性质;如果是指针要判断是存储那种数据类型的地址,如果是数组
- //就要判断数组中存储那种类型的元素,去掉变量之后剩下的数据类型就是其所要存储的地址类型或者元素类型
- //例如:void *p(int)这个时候p就是函数,去掉p(int)之后剩下的是void*就是说这个函数返回值是void*类型的;
- //void (*p)(int)这个时候p就是指针,去掉(*p)之后剩下void (int)就是说它存储的是一个执行返回值为void有一个类型
- //为int的参数的函数的地址;char *p[3],这个时候p就是数组,去掉p[3]之后剩下的是char *即是说这个数组中存储的
- //元素的数据类型是char*的;char (*p)[3]这个时候p就是指针,去掉(*p)剩下的是char [3]就是说p存储的是一个
- //char [3]数组的首地址。复杂的也是从内向外依次拆解
- /*
- void (*pFunc)();
- pFunc = func1;
- (*pFunc)();
- tFunc1(func1);
- float score[][4] = {{60,70,80,90},{56,89,34,45},{34,23,56,45}};//静态创建的时候是开辟了一块连续的空间
- cout << sizeof(float) << endl;
- cout << score << endl; //其实这里score就是存储二维数组的每一行的首地址的一个数组的首地址
- cout << score+1 << endl;
- int m;
- cin >> m;
- float *p = find(score,m);
- for (int i = 0; i < 4;i++)
- {
- cout<< (*(p+i)) << endl;
- }*/
- /***************动态和静态创建的高维数组及数组标识符的含义及类型*******************************/
- /*
- //小结:其实n维数组(静态创建的数组),它的标识符其实就是最高维(从整体看来第n-1维数组)的首地址
- //例如:tri三维数组而言,{{1,2},{3,4}}和{{5,6},{7,8}}是第n-1维数组,它们共同构成了一个三维数组,
- //其实tri就是这两个二位数组的首地址构成的数组的首地址
- //静态创建的数组本质上还是一块连续存储的区域
- int tri[2][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}}};
- //int (**pt)[2] = tri;//编译会报错,因为tri本质上是一个一维数组的首地址,元素是二位数组的首地址
- int (*pt)[2][2] = tri;
- cout << tri << endl;
- cout << tri[0] << endl;
- cout << pt << endl;
- cout << tri + 1 << endl;
- cout << tri[1] << endl;
- cout << pt + 1 << endl;
- //而动态创建的多维数组跟静态创建的数组从结构而言就不是一个概念
- //动态创建的数组各维之间的关系通过上一维中存储的地址来联系,所以不能使用++来就按下一维的地址
- int m,n,p;
- int i = 1;
- int ***pTri;
- pTri = new int **[2];
- for (m = 0; m<2; m++)
- {
- pTri[m] = new int *[2];
- }
- for (m = 0; m < 2; m ++)
- {
- for (n = 0; n < 2; n++)
- {
- pTri[m][n] = new int[2];
- }
- }
- for (m = 0; m< 2; m++)
- {
- for (n = 0; n<2; n++)
- {
- for (p=0; p<2; p++)
- {
- pTri[m][n][p] = i;
- i++;
- }
- }
- }
- for (m = 0; m< 2; m++)
- {
- for (n = 0; n<2; n++)
- {
- for (p=0; p<2; p++)
- {
- cout << pTri[m][n][p] << endl;
- }
- }
- }
- cout << pTri << endl;
- cout << pTri[0] << endl;
- cout << pTri + 1 << endl;
- cout << pTri[1] << endl;*/
- }