数组和指针、数组指针和指针数组、函数指针和指针函数、数组标识符的意义、静态和动态创建的数组的本质区别、标识符类型判断方法
2011-11-04 22:25
926 查看
#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] = new int[2]; } } for (m = 0; m< 2; m++) { for (n = 0; n<2; n++) { for (p=0; p<2; p++) { pTri[m] [p] = i; i++; } } } for (m = 0; m< 2; m++) { for (n = 0; n<2; n++) { for (p=0; p<2; p++) { cout << pTri[m] [p] << endl; } } } cout << pTri << endl; cout << pTri[0] << endl; cout << pTri + 1 << endl; cout << pTri[1] << endl;*/ }
相关文章推荐
- 指针数组,数组指针,指针函数,函数指针的区别及类型间的转换
- 函数的返回值问题(返回指针和数组的区别)静态存储区、动态数据区、栈
- 常量指针、指针常量、指针函数、函数指针、指针数组、数组指针区别在哪里?
- C语言学习8:malloc返回的void*类型指针不可以做更改,free双重释放,二维数组的初始化和打印,a和a[0]和a[0][0]的区别,数组指针(*p)[3],指针数组*a[10],动态内存分配版约瑟夫环,动态分配版去空格和逗号处理,二级指针与二维数组互用
- C++中的指针、数组指针与指针数组、函数指针与指针函数
- JavaScript中判断变量是数组、函数或是对象类型的方法
- 一道二级C题引发的思考-- c++函数传递指针的本质 与 字符串指针与字符数组的区别
- 如何判断送入函数的是静态分配还是动态分配的数组
- C/C++学习之C提高----C数组的定义、类型、定义数组指针变量、多维数组的本质、多维数组做函数参数、将两个数组中的字符串copy到第三个数组
- 数组指针,指针数组,函数指针,指针函数
- 数组指针和指针数组的区别、指针函数与函数指针的区别
- C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数
- C语言学习6 :指针的定义,指针类型要合法,指针要初始化,指针做函数参数,数组和指针的通用性,指针+1所代表的空间,void * 指针,交换函数中的指针,数组和字符型指针区别,字符型指针的应用,使用指针完成字符操作函数
- JavaScript中判断变量是数组、函数或是对象类型的方法
- 指针数组、数组指针、函数指针、指针函数总结
- 创建健壮的isArray()函数(JavaScript中判断对象类型的种种方法)[转]
- 数组指针与指针数组的区别(函数指针与指针函数类似)
- 指针数组,数组指针,函数指针,函数指针数组,指向函数指针数组的指针之间的区别
- C Primer plus 10.2 初始化一个double类型的数组,然后把该数组的内容拷贝至3个其它的数组中,使用带数组的表示方法的函数进行第一份拷贝,使用带指针表示方法和指针递增的函..
- 指针数组和数组指针的区别&指针函数和函数指针的区别