求教关于指针与数组的问题(很纠结D)
跪求高手帮解决这一系列问题。。
困扰我很久的东西,就是分不清, 如下:
1. 为什么 int (*ptr)[] 是 指向整形数组的指针 ,而 int *ptr[] 是存放指针的数组?
然后 int *(ptr[]) 是什么? 跟 int *ptr[]一样吗?
2. 上面这个还不算晕,接着下面的怎么看呢:
2.1 float (**ptr)[10];
2.2 double*(*)ptr[10];
2.3 double(*ptr[10])[];
2.4 int*((*ptr)[10]);
2.5 long (*ptr)(int);
2.1-2.5是在书上看的,书上有答案,但是我就是不明白怎么去看,分不清楚,
求 高手帮下忙,教一下
这指针数组什么的怎么看呢?有什么诀窍吗?
[解决办法]
1.(1)int* p[2] 是一个指向int型的指针数组,即:p是包含两个元素的指针数组,指针指向的是int型。
可以这样来用:
#include <iostream.h>
void main() {
int* p[2];
int a[3] = {1, 2, 3};
int b[4] = {4, 5, 6, 7};
p[0] = a;
p[1] = b;
for(int i = 0; i < 3; i++) cout << *p[0] + i;// cout << **p + i;
cout << endl;
for(i = 0; i < 4; i++) cout << *p[1] + i;// cout << **p + i;
}
(2)对于int (*p)[2], 它相当于一个二维数组的用法,只是它是一个n行2列的数组,可以这样来用:
#include <iostream.h>
void main() {
int (*p)[2];
int b[3][2] = {{1, 2}, {3, 4}, {5, 6}};
p = b;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 2; j++) //cout << p[i][j]; //cout << *(*(p+i)+j);
cout << endl;
}
}
注意:对于(1)为行数确定、列数不确定,即为2*n型的。(2)为n*2型的数组的指针用法,即行数不确定、列数确定。对于(1)其等价形式如下:
#include <iostream.h>
void main() {
int** array;
array = new int* [2];
int a[3] = {1, 2, 3};
int b[4] = {4, 5, 6, 7};
array[0] = a; // *array = a;
array[1] = b; // *(array+1) = b;
for(int i = 0; i < 3; i++) cout << array[0][i];// cout << *array[0] + i;
cout << endl;
for(int j = 0; j < 4; j++) cout << array[1][j];// cout << *array[1] + j;
}
其实以上用法即这我们常用的动态二维数组的用法。
[解决办法]
假设我们说int [3] * 是指向int[3]的指针(从右往左看)
那么C/C++里会写成 int (*)[3],只要看见括号就把括号右边的东西移动到括号左边,就成了int [3] *。
C/C++希望类型的修饰能和变量名写在一起,并且数组大小要写在变量名后面所以创造了这种怪异的写法。
int [3] * * [3] [4] * a; <- a是一个指向4个元素的数组的指针,数组的每个元素是三个元素的数组,后者的元素是指针,指向的又是指针,然后指向的是三个元素的数组,数组的元素是int。
C/C++里写就是 int (**(* a)[3][4])[3]; ...
[解决办法]
http://blog.csdn.net/supermegaboy/article/details/4854965
[解决办法]
与算符(操作符)的优先级有关,是优先级在声明中的使用。
由于优先级设计的规律性,可以用"右左规则"来概括
1.先找声明(定义)中的用户标识符,并设为基点
2.再向右看(因为标识符右边的操作符优先级高(称为后缀算符)--参见LS老ZHAO4提供的表),与标识符拼合理解概念,。。。直至遇到")"(中缀)或";"(表示结束)或"="(表示初始化)
3.再向左看,拼合后理解,直至"("(中缀)或没有了
老ZHAO4提供的表有个小问题,就是表示函数调用操作的后缀()和真正括号操作的中缀()没有区分
对初学者而言括号的概念应该深入一些:
C语言中有三类常用的"小圆括号"
1.分隔作用的符号,如if,for,while等关键字后的()----分界符
2.函数调用的符号,如printf(...)----是printf的后缀算符
3.改变运算次序的符号,如a*(b+c)----是中缀算符
[解决办法]
看指针的原则:从变量名处起,根据运算符优先级结合,一步一步分析.如下:int p; //这是一个普通的整型变量int *p; //首先从P 处开始,先与*结合,所以说明P 是一//个指针,然后再与int 结合,说明指针所指向//的内容的类型为int 型.所以P 是一个返回整//型数据的指针int p[3]; //首先从P 处开始,先与[]结合,说明P 是一个数//组,然后与int 结合,说明数组里的元素是整//型的,所以P 是一个由整型数据组成的数组int *p[3]; //首先从P 处开始,先与[]结合,因为其优先级//比*高,所以P 是一个数组,然后再与*结合,说明//数组里的元素是指针类型,然后再与int 结合,//说明指针所指向的内容的类型是整型的,所以//P 是一个由返回整型数据的指针所组成的数组int (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针//然后再与[]结合(与"()"这步可以忽略,只是为//了改变优先级),说明指针所指向的内容是一个//数组,然后再与int 结合,说明数组里的元素是//整型的.所以P 是一个指向由整型数据组成的数//组的指针int **p; //首先从P 开始,先与*结合,说是P 是一个指针,然//后再与*结合,说明指针所指向的元素是指针,然//后再与int 结合,说明该指针所指向的元素是整//型数据.由于二级指针以及更高级的指针极少用//在复杂的类型中,所以后面更复杂的类型我们就//不考虑多级指针了,最多只考虑一级指针.int p(int); //从P 处起,先与()结合,说明P 是一个函数,然后进入//()里分析,说明该函数有一个整型变量的参数//然后再与外面的int 结合,说明函数的返回值是//一个整型数据Int (*p)(int); //从P 处开始,先与指针结合,说明P 是一个指针,然后与//()结合,说明指针指向的是一个函数,然后再与()里的//int 结合,说明函数有一个int 型的参数,再与最外层的//int 结合,说明函数的返回类型是整型,所以P 是一个指//向有一个整型参数且返回类型为整型的函数的指针int *(*p(int))[3]; //可以先跳过,不看这个类型,过于复杂//从P 开始,先与()结合,说明P 是一个函数,然后进//入()里面,与int 结合,说明函数有一个整型变量//参数,然后再与外面的*结合,说明函数返回的是//一个指针,,然后到最外面一层,先与[]结合,说明//返回的指针指向的是一个数组,然后再与*结合,说//明数组里的元素是指针,然后再与int 结合,说明指//针指向的内容是整型数据.所以P 是一个参数为一个//整数据且返回一个指向由整型指针变量组成的数组//的指针变量的函数.差不多了,基本上够用了
[解决办法]
楼主以后可以对类似题目用一个万能答案回答:(^_^)
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”
提醒:
“学习用汇编语言写程序”
和
“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
不要写连自己也预测不了结果的代码!
对一部电脑而言只有一个二进制字节数组(这里指构成基本内存的RAM和ROM、忽略显存等外设中的存储单元),对人脑才有指针、数组、数组的数组、指针的指针、指针的数组、数组的指针……