c语言二维数组的指针问题

在WinTC下运行如下代码
#include
void main()
{
char a1[][5]={"ab","cd","ef","ghi","sfs"};

printf("%s\n",*(a1+3)); //语句1
printf("%c\n",**(a1+3)); //语句2
}
运行结果为:
ghi
g

但如果将上述语句1中的%s改为%c,即 printf("%c\n",*(a1+3));则无法输出g
这是为什么? * (a1+3) 与 * *(a1+3)的差别是什么,为什么前者只能使用%s输出,它们指向的不都是同一块地址么?

printf("%d\n",*(a1+3)); //语句1
printf("%d\n",**(a1+3)); //语句2
这样就看清楚了,*a1指向的数组保存的是二维数组首地址,而不是首地址内的字符。

vs中调试正常,能获得字符 g

  • (a1+3) 取的 "ghi"
  • *(a1+3) 取的 “g”

char a1[][5]={"ab","cd","ef","ghi","sfs"};定的以为二维数组
printf("%s\n",*(a1+3)); //语句1 中的*(a1+3)指向的是一个字符串
printf("%c\n",**(a1+3)); //语句2 中的**(a1+3)指向的是单个字符
这两个指针指向的起始地址是一样的,但是指向的地址长度不一样。
你用%c去输出一个字符串*(a1+3)肯定是无法正常输出的。

在WinTC中运行printf("%c\n",*(a1+3));结果是一个♠,就是*(a1+3)这个地址的地址阶段之后的值对应变成的。你说的有一点错误的是,两者中只有前者是指向地址,后者是去那个地址里面的值。

指针和值需要区分开来

这份代码你可能会用到
https://github.com/707wk/Senior-middle-school/blob/master/Filling%20in%20the%20gaps.c

#include

int main()
{
return 0;
}


(a+3)这是一个一维的指针!这时候他之指向的是a[3],但是*(a+3)指向的就是a[3][0]所以会出现这种情况

这要仔细看看二维数组的存储以及它和指针的关系。
你定义的数组
char a[][5]={"ab","cd","ef","ghi","sfs"}

存储大概这样子:
** a---- ------>“ab”
(a+1)-----> "cd“
(a+2)------> "ef”
(a+3)------> "ghi“
(a+4)------> "sfs”**

            或者我们可以这样定义:char* a[5]={   "ab","cd","ef","ghi","sfs"}
            这样看的话,a是一个指针,它指向的每一个内容都是一个字符型指针
            我们可以假设指向字符串”ghi“的指针为p,
            所以(a+3)就是指向字符串“ghi”的指针(p)的指针,所以 *(a+3)就取得指向字符串“ghi”的指针p,这样你执行
            printf(“%s”,*(a+3))的时候,程序输出以p为首地址的字符串“ghi“
            **(a+3):
            通过上面分析我们可以看出:*(a+3)就是p,**(a+3)实际上就是*p,*p就是字符串”ghi“第一个字符的值g