猿问

为什么要用双重间接?或者为什么使用指针指向指针?

为什么要用双重间接?或者为什么使用指针指向指针?

在C中什么时候应该使用双重间接?有人能举个例子来解释吗?

我所知道的是,双重间接方向是指向指针的指针。为什么我需要一个指向指针的指针?


九州编程
浏览 952回答 3
3回答

catspeake

如果您想要一个字符列表(一个单词),可以使用char *word如果你想要一个单词列表(一个句子),你可以用char **sentence如果您想要一个句子列表(独白),您可以使用char ***monologue如果您想要一个独白列表(传记),您可以使用char ****biography如果您想要一个传记列表(一个生物库),您可以使用char *****biolibrary如果您想要一个生物库列表(a?lol),可以使用char ******lol... ...是的,我知道这可能不是最好的数据结构一个非常无聊的用法示例LOL#include&nbsp;<stdio.h>#include&nbsp;<stdlib.h>#include&nbsp;<string.h>int&nbsp;wordsinsentence(char&nbsp;**x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;w&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;+=&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;w;}int&nbsp;wordsinmono(char&nbsp;***x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;w&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;+=&nbsp;wordsinsentence(*x); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;w;}int&nbsp;wordsinbio(char&nbsp;****x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;w&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;+=&nbsp;wordsinmono(*x); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;w;}int&nbsp;wordsinlib(char&nbsp;*****x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;w&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;+=&nbsp;wordsinbio(*x); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;w;}int&nbsp;wordsinlol(char&nbsp;******x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;w&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*x)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;+=&nbsp;wordsinlib(*x); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x++; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;w;}int&nbsp;main(void)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*word; &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;**sentence; &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;***monologue; &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;****biography; &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*****biolibrary; &nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;******lol; &nbsp;&nbsp;&nbsp;&nbsp;//fill&nbsp;data&nbsp;structure &nbsp;&nbsp;&nbsp;&nbsp;word&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*word);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;strcpy(word,&nbsp;"foo"); &nbsp;&nbsp;&nbsp;&nbsp;sentence&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*sentence);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;sentence[0]&nbsp;=&nbsp;word; &nbsp;&nbsp;&nbsp;&nbsp;sentence[1]&nbsp;=&nbsp;word; &nbsp;&nbsp;&nbsp;&nbsp;sentence[2]&nbsp;=&nbsp;word; &nbsp;&nbsp;&nbsp;&nbsp;sentence[3]&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;monologue&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*monologue);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;monologue[0]&nbsp;=&nbsp;sentence; &nbsp;&nbsp;&nbsp;&nbsp;monologue[1]&nbsp;=&nbsp;sentence; &nbsp;&nbsp;&nbsp;&nbsp;monologue[2]&nbsp;=&nbsp;sentence; &nbsp;&nbsp;&nbsp;&nbsp;monologue[3]&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;biography&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*biography);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;biography[0]&nbsp;=&nbsp;monologue; &nbsp;&nbsp;&nbsp;&nbsp;biography[1]&nbsp;=&nbsp;monologue; &nbsp;&nbsp;&nbsp;&nbsp;biography[2]&nbsp;=&nbsp;monologue; &nbsp;&nbsp;&nbsp;&nbsp;biography[3]&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;biolibrary&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*biolibrary);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;biolibrary[0]&nbsp;=&nbsp;biography; &nbsp;&nbsp;&nbsp;&nbsp;biolibrary[1]&nbsp;=&nbsp;biography; &nbsp;&nbsp;&nbsp;&nbsp;biolibrary[2]&nbsp;=&nbsp;biography; &nbsp;&nbsp;&nbsp;&nbsp;biolibrary[3]&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;lol&nbsp;=&nbsp;malloc(4&nbsp;*&nbsp;sizeof&nbsp;*lol);&nbsp;//&nbsp;assume&nbsp;it&nbsp;worked &nbsp;&nbsp;&nbsp;&nbsp;lol[0]&nbsp;=&nbsp;biolibrary; &nbsp;&nbsp;&nbsp;&nbsp;lol[1]&nbsp;=&nbsp;biolibrary; &nbsp;&nbsp;&nbsp;&nbsp;lol[2]&nbsp;=&nbsp;biolibrary; &nbsp;&nbsp;&nbsp;&nbsp;lol[3]&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;printf("total&nbsp;words&nbsp;in&nbsp;my&nbsp;lol:&nbsp;%d\n",&nbsp;wordsinlol(lol)); &nbsp;&nbsp;&nbsp;&nbsp;free(lol); &nbsp;&nbsp;&nbsp;&nbsp;free(biolibrary); &nbsp;&nbsp;&nbsp;&nbsp;free(biography); &nbsp;&nbsp;&nbsp;&nbsp;free(monologue); &nbsp;&nbsp;&nbsp;&nbsp;free(sentence); &nbsp;&nbsp;&nbsp;&nbsp;free(word);}产出:total&nbsp;words&nbsp;in&nbsp;my&nbsp;lol:&nbsp;243

慕沐林林

原因之一是要将传递给函数的指针的值更改为函数参数,为此需要指针指向指针。简单地说,使用**当您希望保留(或保留更改)内存分配或赋值时,即使在函数调用之外也是如此。(因此,用双指针Arg传递这样的函数。)这可能不是一个很好的例子,但将向您展示基本用途:void&nbsp;allocate(int**&nbsp;p){ &nbsp;&nbsp;*p&nbsp;=&nbsp;(int*)malloc(sizeof(int));}int&nbsp;main(){ &nbsp;&nbsp;int*&nbsp;p&nbsp;=&nbsp;NULL; &nbsp;&nbsp;allocate(&p); &nbsp;&nbsp;*p&nbsp;=&nbsp;42; &nbsp;&nbsp;free(p);}

临摹微笑

这里有一个简单的答案!假设您有一个指针,它的值是一个地址。但现在你想改变那个地址。您可以执行pointer1=pointer2,pointer1现在有pointer2的地址。但!如果您想要一个函数为您做这件事,并且您希望在函数完成后结果保持不变,那么您需要做一些额外的工作,您需要一个新的pointer3来指向pointer1,并将pointer3传递给该函数。下面是一个有趣的示例(先看看输出下面的内容,了解一下!):#include&nbsp;<stdio.h>int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;c&nbsp;=&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;d&nbsp;=&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;e&nbsp;=&nbsp;3; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;*&nbsp;a&nbsp;=&nbsp;&c; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;*&nbsp;b&nbsp;=&nbsp;&d; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;*&nbsp;f&nbsp;=&nbsp;&e; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;**&nbsp;pp&nbsp;=&nbsp;&a;&nbsp;&nbsp;//&nbsp;pointer&nbsp;to&nbsp;pointer&nbsp;'a' &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;a's&nbsp;value:&nbsp;%x&nbsp;\n",&nbsp;a); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;b's&nbsp;value:&nbsp;%x&nbsp;\n",&nbsp;b); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;f's&nbsp;value:&nbsp;%x&nbsp;\n",&nbsp;f); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;can&nbsp;we&nbsp;change&nbsp;a?,&nbsp;lets&nbsp;see&nbsp;\n"); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;a&nbsp;=&nbsp;b&nbsp;\n"); &nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;%x,&nbsp;same&nbsp;as&nbsp;'b'...&nbsp;it&nbsp;seems&nbsp;we&nbsp;can,&nbsp;but&nbsp;can&nbsp;we&nbsp;do&nbsp;it&nbsp;in&nbsp;a&nbsp;function?&nbsp;lets&nbsp;see...&nbsp;\n",&nbsp;a); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;cant_change(a,&nbsp;f);&nbsp;\n"); &nbsp;&nbsp;&nbsp;&nbsp;cant_change(a,&nbsp;f); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;%x,&nbsp;Doh!&nbsp;same&nbsp;as&nbsp;'b'...&nbsp;&nbsp;that&nbsp;function&nbsp;tricked&nbsp;us.&nbsp;\n",&nbsp;a); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;NOW!&nbsp;lets&nbsp;see&nbsp;if&nbsp;a&nbsp;pointer&nbsp;to&nbsp;a&nbsp;pointer&nbsp;solution&nbsp;can&nbsp;help&nbsp;us...&nbsp;remember&nbsp;that&nbsp;'pp'&nbsp;point&nbsp;to&nbsp;'a'&nbsp;\n"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;change(pp,&nbsp;f);&nbsp;\n"); &nbsp;&nbsp;&nbsp;&nbsp;change(pp,&nbsp;f); &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;%x,&nbsp;YEAH!&nbsp;same&nbsp;as&nbsp;'f'...&nbsp;&nbsp;that&nbsp;function&nbsp;ROCKS!!!.&nbsp;\n",&nbsp;a); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}void&nbsp;cant_change(int&nbsp;*&nbsp;x,&nbsp;int&nbsp;*&nbsp;z){ &nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;z; &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;---->&nbsp;value&nbsp;of&nbsp;'a'&nbsp;is:&nbsp;%x&nbsp;inside&nbsp;function,&nbsp;same&nbsp;as&nbsp;'f',&nbsp;BUT&nbsp;will&nbsp;it&nbsp;be&nbsp;the&nbsp;same&nbsp;outside&nbsp;of&nbsp;this&nbsp;function?&nbsp;lets&nbsp;see\n",&nbsp;x);} &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;change(int&nbsp;**&nbsp;x,&nbsp;int&nbsp;*&nbsp;z){ &nbsp;&nbsp;&nbsp;&nbsp;*x&nbsp;=&nbsp;z; &nbsp;&nbsp;&nbsp;&nbsp;printf("\n&nbsp;---->&nbsp;value&nbsp;of&nbsp;'a'&nbsp;is:&nbsp;%x&nbsp;inside&nbsp;function,&nbsp;same&nbsp;as&nbsp;'f',&nbsp;BUT&nbsp;will&nbsp;it&nbsp;be&nbsp;the&nbsp;same&nbsp;outside&nbsp;of&nbsp;this&nbsp;function?&nbsp;lets&nbsp;see\n",&nbsp;*x);}这是输出:&nbsp;a's&nbsp;value:&nbsp;bf94c204 &nbsp;b's&nbsp;value:&nbsp;bf94c208&nbsp; &nbsp;f's&nbsp;value:&nbsp;bf94c20c&nbsp; &nbsp;can&nbsp;we&nbsp;change&nbsp;a?,&nbsp;lets&nbsp;see&nbsp; &nbsp;a&nbsp;=&nbsp;b&nbsp; &nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;bf94c208,&nbsp;same&nbsp;as&nbsp;'b'...&nbsp;it&nbsp;seems&nbsp;we&nbsp;can,&nbsp;but&nbsp;can&nbsp;we&nbsp;do&nbsp;it&nbsp;in&nbsp;a&nbsp;function?&nbsp;lets&nbsp;see...&nbsp; &nbsp;cant_change(a,&nbsp;f);&nbsp; &nbsp;---->&nbsp;value&nbsp;of&nbsp;'a'&nbsp;is:&nbsp;bf94c20c&nbsp;inside&nbsp;function,&nbsp;same&nbsp;as&nbsp;'f',&nbsp;BUT&nbsp;will&nbsp;it&nbsp;be&nbsp;the&nbsp;same&nbsp;outside&nbsp;of&nbsp;this&nbsp;function?&nbsp;lets&nbsp;see &nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;bf94c208,&nbsp;Doh!&nbsp;same&nbsp;as&nbsp;'b'...&nbsp;&nbsp;that&nbsp;function&nbsp;tricked&nbsp;us.&nbsp; &nbsp;NOW!&nbsp;lets&nbsp;see&nbsp;if&nbsp;a&nbsp;pointer&nbsp;to&nbsp;a&nbsp;pointer&nbsp;solution&nbsp;can&nbsp;help&nbsp;us...&nbsp;remember&nbsp;that&nbsp;'pp'&nbsp;point&nbsp;to&nbsp;'a'&nbsp; &nbsp;change(pp,&nbsp;f);&nbsp; &nbsp;---->&nbsp;value&nbsp;of&nbsp;'a'&nbsp;is:&nbsp;bf94c20c&nbsp;inside&nbsp;function,&nbsp;same&nbsp;as&nbsp;'f',&nbsp;BUT&nbsp;will&nbsp;it&nbsp;be&nbsp;the&nbsp;same&nbsp;outside&nbsp;of&nbsp;this&nbsp;function?&nbsp;lets&nbsp;see &nbsp;a's&nbsp;value&nbsp;is&nbsp;now:&nbsp;bf94c20c,&nbsp;YEAH!&nbsp;same&nbsp;as&nbsp;'f'...&nbsp;&nbsp;that&nbsp;function&nbsp;ROCKS!!!.
随时随地看视频慕课网APP
我要回答