c语言解惑 指针,解读:《C语言解惑》中的难解的指针

在C语言中,指针和数组有着千丝万缕的关系,也是很核心的内容之一,同时也是最难理解的部分。在 《C语言解惑》一书中有一道关于指针的题目,作者说只要能正确地解答之,便说明已经全面地掌握了C语言中指针的用法。

让我们先看看源代码:

int main()

{

char * c[] = {

"ENTER",

"NEW",

"POINT",

"FIRST"

};

char ** cp[] = { c + 3, c + 2, c + 1, c };

char *** cpp = cp;

printf("%s \n",* * ++cpp );

printf("%s \n",* -- * ++cpp + 3 );

printf("%s \n",* cpp[ -2 ] + 3 );

printf("%s \n", cpp[ -1 ][ -1 ] +1 );

int i;

scanf("%d",&i);

return 0;

}

在看结果之前,最好能够静下心来做一做。

运行结果:

d61faf55717042a48e114bb64f49746e.jpg

为了能够较为明了地分析,将源代码改为如下:

#includechar * c[] = {

"ENTER",

"NEW",

"POINT",

"FIRST"

};

char ** cp[] = { c + 3, c + 2, c + 1, c };

char *** cpp = cp;

int main()

{

printf( "------------START_111----------\n");

Printf(); // 输出一

printf( "------------END_111----------\n");

++ cpp;

printf(" %s \n",* *cpp );

printf( "------------START_222----------\n");

Printf(); //输出二

printf( "------------END_222----------\n");

++cpp;

printf( "------------START_333----------\n");

Printf(); //输出三

printf( "------------END_333----------\n");

-- * cpp;

printf(" %s \n",* * cpp + 3 );

printf( "------------START_444----------\n");

Printf(); //输出四

printf( "\n------------END_444----------\n");

printf("\n\ncpp[ - 2 ] = %x , * cpp[ -2 ] = %x, * cpp[ -2 ] + 3 = %x\n",

cpp[ - 2 ], * cpp[ -2 ], * cpp[ -2 ] + 3 );

printf("* cpp[ -2 ] + 3 = %s \n",* cpp[ -2 ] + 3 );

printf("\n\ncpp[ - 1 ] = %x , cpp[ -1 ][ - 1] = %x, cpp[ -1 ][ - 1] + 1 = %x\n",

cpp[ - 1 ], cpp[ -1 ][ - 1], cpp[ -1 ][ - 1] + 1 );

printf(" cpp[ -1 ][ -1 ] +1 = %s \n", cpp[ -1 ][ -1 ] +1 );

int i;

scanf("%d",&i);

return 0;

}

其中Printf函数代码如下:

void Printf()

{

printf( "cpp = %x; &cpp = %x; *cpp = %x ;\n\n", cpp , &cpp, *cpp );

printf( "cp = %x; &cp = %x; *cp = %x; \n\n", cp , &cp, *cp );

printf( "cp+1 = %x; &cp+1 = %x; *(cp+1) = %x; \n\n",

cp + 1 , &cp + 1 , * ( cp + 1 ) );

printf( "cp+2 = %x; &cp+2 = %x; *(cp+2) = %x; \n\n",

cp + 2 , &cp + 2 , * ( cp + 2 ) );

printf( "cp+3 = %x; &cp+3 = %x; *(cp+3) = %x; \n\n",

cp + 3 , &cp + 3 , * ( cp + 3 ) );

printf( "c = %x; &c = %x; *c = %x; \n\n",

c , &c , *c );

printf( "c+1 = %x; &c+1 = %x; *(c+1) = %x; \n\n",

c + 1 , &c + 1 , * ( c + 1 ) );

printf( "c+2 = %x; &c+2 = %x; *(c+2) = %x; \n\n",

c + 2 , &c + 2 , * ( c + 2 ) );

printf( "c+3 = %x; &c+3 = %x; *(c+3) = %x; \n\n",

c + 3 , &c + 3 , * ( c + 3 ) );

printf("ENTER : %x : %s \n", c[ 0 ], c[ 0 ] );

printf("NEW : %x : %s \n", c[ 1 ], c[ 0 ] );

printf("POINT : %x : %s \n", c[ 2 ], c[ 2 ] );

printf("FIRST : %x : %s \n", c[ 3 ], c[ 3 ] );

}

改变为以上形式是为了清楚地看到地址。

运行结果如下图: 截图一:

83aedfe31393406e8bce24dbdbabe0fb.jpg

截图二

6559816373b34637b1ed09b509cf91f4.jpg

截图三:

4d0e2c52b5e84803b7c220007c90bed2.jpg

截图四:

874d0be9f42d46d1b6b97fafc4b7825a.png

为了对比方便,故以以上方式截图。

图的说明:

共有四个输出位于START_111和END_111,START_222和END_222,START_333和END_333,START_444和END_444之间。为了对比方便,在截图一中的START_222和END_222间的内容与截图二中的START_222和END_222间的内容完全一样,只不过在截图时对START_222和END_222间的内容截了两次,截图二与截图三中的START_333和END_333的内容也一样。

为了更精确地说明,画如下包含地址的图:

START_111和END_111的内容如下图:

fe878d70a07d958c97c618b3c5bbdc86.png

1290610953850789888.htm

START_222和END_222的内容如下图:

9efb4108e4df420dd696caa4a6b1c2a5.png

1290610953850789888.htm

START_333和END_333的内容如下图:

51f5c827e236ab12a3df5c4c6412c21b.png

1290610953850789888.htm

START_444和END_444的内容如下图:

1290610953850789888.htm432e59c81160f109ab2e4eaf49475168.png

说明:

上面的图中,cpp表示变量名,用 int i = 0;来类比,cpp相当于i,cpp的地址78020相当于&i,而其中的内容78018(对于地址图四)相当于0;但是cp和c不同,它们都是数组名,是常量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值