void fun(char **p)
{
}
void test0(void)
{
char *p[10]; //指针数组 *p[10]=*(p[10]) 即数组里的所有元素皆为指针类型的,例子:表示有10个指针
char buf[10]="1234567890";
//p = buf 为错误语句,因为二级指针不能指向一级指针
//每一个指针都可以指向一段连续的内存空间
*p=buf; // p[0] = buf;
for( int i=0;i<strlen(buf);i++ )
{
printf(" %c \n",*(p[0]+i));
}
printf("********************\n");
for( int j=0;j<strlen(buf);j++ )
{
printf(" %c \n",*(*p+j));
}
// *p = p[0] 它都指代数组的元素的第一个指针,
// p是p[10]这个数组的首地址即p=&p[0]
// 则
// p+1 = &p[1]
// p+2 = &p[2]
// p+3 = &p[3]
// p+4 = &p[4]
// p的自增相当于历遍p[10]这个数组 以此类推
// 那么*p等于取数组里面的值 即 *p=p[0],
// 而数组里面的值它是一个指针,它类似于你直接定义了一个 char *ptr 的指针 ptr=p[0]=*p
// 而数组的元素又指向buf
// 要想读出 buf 里面元素的值又两种写法
// buf[0] = *(*p)=*(p[0]) 即再对指针数组的指针再取一次值便可
// for( int i=0;i<strlen(buf);i++ )
// {
// printf(" %c \n",*(p[0]+i));
// }
// printf("********************\n");
// for( int j=0;j<strlen(buf);j++ )
// {
// printf(" %c \n",*(*p+j));
// }
// 往复循环则可以读出buf 数组里面所有的值
// 若要将指针数组作为实参传递给函数的形参该怎么写呢
// 其实 p作为实参经过上面分析你应该知道他是个二级指针了
// p指向数组p[10]
// p的偏移是在数组p[10]上偏移
// *p是取数组的值
// fun(p);
}
void test1(void)
{
char *p[3]={"11111111","222222222","3333333333"};
char **q;
q=p;
for(int i=0;i<(sizeof(p)/sizeof(int));i++)
{
printf("%s \n",*(q+i));
}
printf("********************\n");
for( int i=0;i<strlen(p[0]);i++ )
{
printf("%c ",*(*q+i));
}
printf("\n");
for(int i=0;i<(sizeof(p)/sizeof(int));i++)
{
printf("%s \n",p[i]);
}
printf("********************\n");
for( int i=0;i<strlen(p[0]);i++ )
{
printf("%c ",*(p[0]+i));
}
printf("\n");
}
void test2(void)
{
char array[4][3]={{1,2,3},{4,5,6},{7,8,9},{0,1,2}};
// char **p=array; //错误的语句
printf("行数=%d 列数=%d\n",sizeof(array)/sizeof(array[0]),sizeof(array[0]));
printf("strlen(array[0])=%d strlen(array[1])=%d\n",strlen(array[0]),strlen(array[1]));
for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
{
for( int j=0;j<sizeof(array[0]);j++ )
{
printf("%d ",array[i][j]);
}
printf("\n");
}
printf("********************\n");
for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
{
for( int j=0;j<sizeof(array[0]);j++ )
{
printf("%d ",*(*(array+i)+j));
}
printf("\n");
}
printf("********************\n");
for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
{
for( int j=0;j<sizeof(array[0]);j++ )
{
printf("%d ",*(array[i]+j));
}
printf("\n");
}
// 注意1: array是一个指向数组的行指针,它虽然是一个二级指针,但不等直接等效 **p=array,这是错误的表达
// 那么二维数组 在语句和参数传递中如何等效
// char (*p)[3]; //数组指针也叫行指针,即该指针指向一个有三个元素的一维数组
// p = array;
// 这里说明了二维数组等效于一个数组指针=行指针
// 注意2: sizeof(array)=12 计算的是二维数组开辟的存储空间,且数组的类型是char 占一个字节,所以大小为12
// sizeof(array[0])=3 计算的二维数组每一行开辟的存储空间,数组有三个元素,char类型,所以大小为3
// 那么可以用 strlen(array[0]) 计算每行有多少元素吗?
// 不可以,因为二维数组的元素也是连续的存储的,这样计算的是 strlen(array[0])=12 strlen(array[1])=9
// 注意3:
// array = &array[0]
// array+1 = &array[1]
// array+2 = &array[2]
// array+3 = &array[3]
// array 该指针表示指向数组的第一个行地址,它的历遍的是array[4]这个数组,这个数组全是行指针,每一个都指向一个一维数组
// 那么它取值
// *array = array[1] 表示获得一个列指针
// *(*array+0)
// *(*array+1)
// *(*array+2)
// 那么*array这个指针历遍的就是列指针指向的一维数组,它的在取值即 *(*array)=表示第一行第一列的值 然后依次类推
}
void fun1( char (*q)[3] )
{
for(int i=0;i<4;i++)
{
for( int j=0;j<sizeof((*q));j++ ) //*q=列指针 q=行指针
{
printf("%d ",(*(q+i))[j]);
}
printf("\n");
}
}
void test3(void)
{
char array[4][3]={{1,1,1},{2,2,2},{4,4,4},{5,5,5}};
char (*p)[3]; //数组指针即p是一个指向一个一维数组的指针又称行指针,
p=array; //array就是二维数组首地址,也是一个行指针
for(int i=0;i<(sizeof(array)/sizeof(array[0]));i++)
{
for( int j=0;j<sizeof(array[0]);j++ )
{
printf("%d ",(*(p+i))[j]);
}
printf("\n");
}
printf("********************\n");
for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
{
for( int j=0;j<sizeof(array[0]);j++ )
{
printf("%d ",*(*(p+i)+j));
}
printf("\n");
}
// 注意1: array是一个指向数组的行指针,它虽然是一个二级指针,但不等直接等效 **p=array,这是错误的表达
// 那么二维数组 在语句和参数传递中如何等效
// char (*p)[3]; //数组指针也叫行指针,即该指针指向一个有三个元素的一维数组
// p = array;
// 这里说明了二维数组等效于一个数组指针=行指针
fun1(array);
}
void main(void)
{
test0();
test1();
test2();
test3();
}
参考链接
二维数组和指针
C/C++二维数组名和二级指针
C语言数组之指针数组和数组指针
C/C++二维数组指针(指向二维数组的指针)详解