#define MAX 10
char* ch1[MAX];// max个字符串 (指针数组)
(char*) ch2[MAX];//错误 在vc6上编译不过
char (* ch3)[MAX];//含有MAX个字符的指针;即数组指针
ch3=(char (*)[12])malloc(12);
or
ch3 = &ch1;
ch1={"hello","world",};
ch3 ={"nihaoa"}; //错误 在vc6上编译不过
部分摘自:http://ankorzhang.blog.163.com/blog/static/11837734320097261073438/
int *p[2]; 首先声明了一个数组,数组的元素是int型的指针。
int (*p)[2]; 声明了一个指针, 指向了一个有两个int元素的数组。
通常,对于int a[8][9]这个二维数组,我们可以这样定义一个指向它的指针:
int (*p)[9];
这个声明的形式跟人们所熟悉的int *p的形式大相庭径,初学者通常会感到迷惑,不理解的地方大致有四个:
1。为什么会以这种形式声明?
2。(*p)应该如何理解?
3。为什么必须把第二维显式地声明?
4。为什么忽略第一维?
下面我们就一起逐个讨论这四个问题:
1。这种形式是C标准的声明语法规定的,由于本章不是对标准的解释,只是对标准的应用,因此笔者尽量以简洁的方式解释这个声明,详细的讨论将在第七章进行。C标准的声明包含了两部分:
声明:
声明说明符 初始化声明符表opt (opt的意思是可选)
在声明说明符里面有一项类型说明符,int就是这种类型说明符。而初始化声明符表里面的其中一种形式,就是:
直接声明符 [常量表达式opt]
(*p)[9]就是这种直接声明符加[]的形式。
2。p左边的*在这里不是取值运算符,而是一个声明符,它指出p是一个指针。而()括号是不能去掉的,如果去掉了,由于[]运算符优先级比*高,p就会先跟[]结合,这样p就变成了一个指针数组,而不是指向数组的指针。
题外话:
*p还有一种用法,就是当*是取值运算符的时候,*p是一个左值,表示一个变量,为什么*p是一个变量呢?也许有人会说,因为int i, *p=&i嘛,其实这是结果不是原因。严格来说,i只是一个变量名,不是变量,在编译器的符号表里面,变量名是一个符号地址,它所代表的地址值是它指向的那段内存单元的地址,真正叫变量的是那段内存单元,懂汇编的朋友能很容易地区分出来,在汇编里面,可以这样定义一个变量名:
VARW DW 10,20
VARW就是一个变量名,它在汇编里面是一个地址,代表了10所在的内存单元这个变量。由于p被初始化为&i,*p指向i所代表的那段内存单元,因此说*p是一个变量。把i称为变量是一种习惯上的统称。
3。定义一个指针的时候,首先必须定出指针的类型,由于这是一个指向数组的指针,如果数组的元素的类型定下来了,那么这个指针的类型也就定下来了。前面说过,C语言的多维数组实质上是数组的嵌套,那么所指向数组的元素必定具有数组类型,也就是说,这个数组的元素是一个具有6个int元素的数组,因此,p定义的时候,必须指定第二维的上界,这样才能把p的类型定下来。
4。有这种疑问的人已经犯了一个错误,没有分清楚什么是指针,什么是数组,以数组的思维模式来看待这个指针p。定义一个数组(非static)的时候,需要在栈中静态分配一块内存,那么就需要知道这块内存的大小,因此定义数组时需要确定各维的上界。而这里只是定义一个指针而已,对于一个指针的定义,需要知道的是它所指向对象的类型,并不需要知道对象的大小,这是多余的。因此,所有指向数组的指针的第一维被忽略。
以上介绍了如何声明一个指向二维数组的指针,类似地,对一个指向n维数组的指针也可以用同样的方法来声明,如下:
int (*p)[x2][x3]......[xn];
同样可以忽略第一维,而其它维必须指定上界。
最后再讨论一种很常见的对多维数组的错误理解,有些人常常会以为,二维数组就是二级指针,这种错误的根源,来自于可以把一个二级指针int **p以p[i][j]这种形式使用。首先把数组称为指针就是错误的,第一章笔者已经说明了数组名是地址,不能理解为指针。第二,并非能以p[i][j]这种形式使用,那么p就是一个二维数组了,C标准对数组引用的规定,并没有指定数组引用时[]运算符的左边必须是数组名,而可以是一个表达式。第三,这是一种“巧合”,归根到底是由于C语言的数组实现是数组的嵌套同时C标准把[]运算符转换为类似*(*(a+i)+j)这样的等价表达式造成的,那两个取值运算符“恰好”可以用于一个二级指针。第四,p与p[i]并不具有数组类型,sizeof(p)和sizeof(p[i])的结果只是一个指针的大小4字节。而对于一个真正的数组,p与p[i]都是具有数组类型的地址。
实际上,int **p只是一个指向一维指针数组的指针,而不是指向二维数组的指针。同样地,对于n级指针,都可以看作一个指向一维指针数组的指针,这个指针数组的元素都是n-1级指针。
【huashizhixin】:
一个指向十个int元素的指针
可以这样赋值:int b[10]={0};//必须是十个元素
p=&b;
【huashizhixin】:
(i)int *p[3];
(ii)int (*q)[3];
(iii)int *(t[3]);
以上三者的区别?(vc++环境下验证):
(1)p是一个指针数组,此处包含三个整型指针,所以sizeof(p)=12;sizeof(*p)=4;//首地址
(2)q是一个数组指针,指向含有三个元素的整型数组,所以sizeof(q)=4;sizeof(*q)=12;
(3) 和(1)一样;sizeof(t)=12;sizeof(*t)=4;
(4) int *p[3]等价于:typedef int* myint;
myint p[3];
int (*p)[3]等价于:typedef int intarray[3];
intarray *p;
(5) (i)可以这样初试化:int a[]={1,2,3,4};
p[0]=a;//*p=a;
(ii)可以这样初始化:int a[3]={1,2,3};//数组元素必须是三个
q =&a;
(6)p是数组,不可做++操作,q是指针,可以做++操作,q++是当前q指向的地址值加12;
【hongliuhongwei】:
谢谢大家,能不能给我一个使用的例子啊,我是在使用的时候,编译能通过,一执行就有问题,没有结果,谢谢!
【huashizhixin】:
vc6.0
#include"stdio.h"
main(int argc, char *argv[ ])
{
int b[3]={1,2,3};
int (*p)[3];
p=&b;
for(int i=0;i<3;i++)
printf("%5d",*(*p+i));
}
【cuibo1123】:
int (*p)[10]
整形 指针 10个元素
意思就是一个指针,可以指向包含10个整形元素的东西~
int main(void)
{
int a[5][10]={1};//5行10列的数组(也就是5个 《包含10个整形元素》 的数组)
int (*p)[10];//可以指向包含10个整形元素的指针(他的基类型是sizeof(int)*10)
p=a;
printf("%d",p[0][0]);
return 0;
}