双指针vs指针数组(**数组vs * array )

我不清楚这些之间有什么区别2.我的教授写道**数组与* array []相同,我们得到一个例子,他用**数组(所以在课后我尝试用* array交换它] ]它没有用),谁能告诉我这些2是否与他写的一样? 无论如何,这个类是关于动态内存分配的

@一旦我改变了双指针,这一行开始抛出错误

lines = malloc(sizeof(char*)); 

以及其他一些内存正在重新分配的地方

@ 2地狱耶,这是整个代码

对于那些评论,但是因为他的陈述是,所以内部没有任何内容

  **array = *array[] 

大更新

对于给您带来的任何不便,我感到非常抱歉,在写这篇文章时我太累了,这里是整个代码,没有编辑

  #include  #include  #include  char **lines; // global text buffer, organized as an array of lines // -------------------------------------------------------------------------------- // initialize global buffer void initialize() { lines = malloc(sizeof(char*)); lines[0] = NULL; } // -------------------------------------------------------------------------------- // return number of lines in buffer int countLines() { int count = 0; while(lines[count++]) ; return count-1; } // -------------------------------------------------------------------------------- // print one line void printLine(int line) { printf("Line %d: %p %p %s\n",line, &lines[line], lines[line], lines[line]); } // -------------------------------------------------------------------------------- // print all lines void printAll() { int num_lines = countLines(); int line = 0; printf("----- %d line(s) ----\n",num_lines); while (line = 0) free(lines[line--]); free(lines); } // -------------------------------------------------------------------------------- // insert a line before the line specified void insertLine(int line, char *str) { int num_lines = countLines(); // increase lines size by one line pointer: lines = realloc(lines, (num_lines+2) * sizeof(char*)); // move line pointers backwards: memmove(&lines[line+1], &lines[line], (num_lines-line+1)*sizeof(char*)); // insert the new line: lines[line] = malloc(strlen(str)+1); strcpy(lines[line],str); } // -------------------------------------------------------------------------------- // remove the specified line void removeLine(int line) { int num_lines = countLines(); // free the memory used by this line: free(lines[line]); // move line pointers forward: memmove(&lines[line], &lines[line+1], (num_lines-line+1)*sizeof(char*)); // decrease lines size by one line pointer: lines = realloc(lines, num_lines * sizeof(char*)); } // -------------------------------------------------------------------------------- // insert a string into specified line at specified column void insertString(int line, int col, char *str) { // make room for the new string: lines[line] = realloc(lines[line], strlen(lines[line])+strlen(str)+1); // move characters after col to the end: memmove(lines[line]+col+strlen(str), lines[line]+col, strlen(lines[line])-col); // insert string (without terminating 0-byte): memmove(lines[line]+col, str, strlen(str)); } // -------------------------------------------------------------------------------- // MAIN program int main() { initialize(); printAll(); insertLine(0,"Das ist"); printAll(); insertLine(1,"Text"); printAll(); insertLine(1,"ein"); printAll(); insertLine(2,"kurzer"); printAll(); printf("lines[2][4] = %c\n",lines[2][4]); insertString(2,0,"ziemlich "); printAll(); removeLine(2); printAll(); freeAll(); return 0; } 

如果您的问题中引用的代码是由您的教授提供给您的,作为使用指针指针数组的示例,我不确定该类实际上会做多少好事。 我怀疑它是作为调试练习提供的,或者可能是您尝试解决方案。 无论如何,如果您只是在启用警告的情况下进行编译,那么在进行调试代码之前,您会发现许多需要注意的问题。

关于您引用的代码,当您可以自由使用全局文本缓冲区时,通过不使用全局缓冲区并根据需要将指针传递给数据,可以更好地服务。 有些实例,各种回调函数等需要全局数据,但根据经验,这些是例外而不是规则。

你的问题基本上归结为“我如何正确使用指针和双指针(指向指针到类型的指针)变量的数组。在一个答案中没有办法完全涵盖主题,因为有远太多的情况和背景,其中一个或另一个可以(或应该)使用,为什么。但是,一些例子有望帮助你理解基本的差异。

要键入的指针数组开始(例如char *array[] )。 它通常以该forms看作函数参数。 声明为变量时,会进行初始化。 例如:

 char *array[] = { "The quick", "brown fox", "jumps over", "the lazy dog." }; 

char *array[]; 由于[..]之间缺少数组大小,变量声明本身无效。 当全局使用时,如在您的示例中,编译器将接受声明,但将警告声明假定具有一个元素

上面声明的array元素是指向char类型的指针。 具体来说,元素是指向声明创建的字符串文字的指针。 每个字符串都可以由array的关联指针作为array[0], ... array[3]

指向类型 (双指针)指针的指针正如其名称所暗示的那样。 它是一个指针 ,它将指针作为其值。 在基本术语中,它是指向另一个指针的指针。 它可以通过分配array的地址来访问上面数组的成员,如:

 char **p = array; 

其中p[1]*(p + 1)指向"brown fox"等。

或者,可以动态地分配指向类型指针的多个指针并用于创建指向要键入的指针数组,然后可以对其进行分配和重新分配以处理对未知数量的元素的访问或存储。 例如,从stdin读取未知行数的简短示例,您可能会看到:

 #define MAXL 128 #define MAXC 512 ... char **lines = NULL; char buf[MAXC] = {0}; lines = malloc (MAXL * sizeof *lines); size_t index = 0; ... while (fgets (buf, MAXC, stdin)) { lines[index++] = strdup (buf); if (index == MAXL) /* reallocate lines */ } 

上面有lines ,一个指向char的指针,最初是NULL ,用于分配MAXL (128)指针到char。 然后将行从stdin读入buf ,在每次成功读取后,分配存储器以保存buf的内容,并将每个存储器块的结果起始地址分配给每个指针line[index] ,其中index0-127 ,并且在index增加到128时,重新分配index以提供附加指针并继续读取。

使主题大于可以在任何一个答案中处理的是, 指针数组指向类型指针的指针可以是任何type 。 ( intstruct ,或作为不同类型或function等的结构的成员…)它们可以在目录列表(例如opendir )的返回中使用链接列表 ,或者以任何其他方式使用。 它们可以静态初始化,动态分配,作为函数参数传递等等……有太多不同的上下文可以覆盖它们。 但在所有情况下,他们都将遵循此处和此处的另一个答案中的一般规则,并在StackOverflow上的1,000个更多答案中。

我将以一个简短的示例结束,您可以使用它来查看数组和双指针的不同基本用法。 我在源代码中提供了其他评论。 这只提供了一些不同的基本用法以及静态声明和动态分配:

 #include  #include  #include  int main (void) { /* array is a static array of 4 pointers to char, initialized to the 4 string-literals that a part of the declaration */ char *array[] = { "The quick", "brown fox", "jumps over", "the lazy dog." }; /* p is a pointer-to-pointer-to-char assigned the address of array */ char **p = array; /* lines is a pointer-to-pointer-to-char initialized to NULL, used below to allocate 8 pointers and storage to hold 2 copes of array */ char **lines = NULL; size_t narray = sizeof array/sizeof *array; size_t i; printf ("\nprinting each string-literal at the address stored by\n" "each pointer in the array of ponters named 'array':\n\n"); for (i = 0; i < narray; i++) printf (" %s\n", array[i]); printf ("\nprinting each string using a pointer to pointer to char 'p':\n\n"); for (i = 0; i < narray; i++, p++) printf (" %s\n", *p); p = array; printf ("\nprinting each line using a pointer to pointer" " to char 'p' with array notation:\n\n"); for (i = 0; i < narray; i++) printf (" %s\n", p[i]); /* allocate 8 pointers to char */ lines = malloc (2 * narray * sizeof *lines); /* allocate memory and copy 1st 4-strings to lines (long way) */ for (i = 0; i < narray; i++) { size_t len = strlen (array[i]); lines[i] = malloc (len * sizeof **lines + 1); strncpy (lines[i], array[i], len); lines[i][len] = 0; } /* allocate memory and copy 1st 4-strings to lines (using strdup - short way) */ // for (i = 0; i < narray; i++) // lines[i] = strdup (array[i]); /* allocate memory and copy again as last 4-strings in lines */ p = array; for (i = 0; i < narray; i++, p++) lines[i+4] = strdup (*p); p = lines; /* p now points to lines instead of array */ printf ("\nprinting each allocated line in 'lines' using pointer 'p':\n\n"); for (i = 0; i < 2 * narray; i++) printf (" %s\n", p[i]); /* free allocated memory */ for (i = 0; i < 2 * narray; i++) free (lines[i]); free (lines); return 0; } 

如果您有任何疑问,请告诉我。 这是一个规模相对较小的大型主题,可以在不同的方式和不同的环境中应用。

我的教授写道, **array*array[]相同

在某些情况下也是如此,在其他情况下则不然。

如果在函数中用作参数,

 void foo(int **array) {} 

是相同的

 void foo(int *array[]) {} 

当声明为变量时

 int **array; 

是不一样的

 int *array[]; 

免责声明:这绝不是一份详尽的清单,列出了它们的相同之处和不同之处。