Max*_*itj 12 c pointers multidimensional-array dynamic-memory-allocation
我不清楚这些之间的区别是什么2.我的教授写道**数组与*array []相同,我们得到了一个例子,他使用了**数组(所以在类之后我尝试用*array交换它] ]它没有用),谁能告诉我这些2是否与他写的一样?无论如何,这个类是关于动态内存分配的
@一旦我改变了双指针,这一行开始抛出错误
lines = malloc(sizeof(char*));
Run Code Online (Sandbox Code Playgroud)
以及其他一些内存重新分配的地方
@ 2地狱耶,这是整个代码
对于那些评论吼叫,因为他的陈述是,因为[]内部没有任何内容
**array = *array[]
Run Code Online (Sandbox Code Playgroud)
大新闻
对于给您带来的任何不便,我感到非常抱歉,在写这篇文章的时候我太累了,这里是整个代码,没有编辑
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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 < num_lines)
printLine(line++);
printf("---------------------\n");
}
// --------------------------------------------------------------------------------
// free whole buffer
void freeAll()
{
int line = countLines();
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;
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ica 12
如果你的问题中提到的代码是由你的教授给你的,作为使用指针指针指针数组的一个例子,我不确定该类实际上会做多少好事.我怀疑它是作为调试练习提供的,或者可能是您尝试解决方案.无论如何,如果您只是在启用警告的情况下进行编译,那么在进行调试代码之前,您会发现许多需要注意的问题.
关于您引用的代码,当您可以自由使用全局文本缓冲区时,通过不使用全局缓冲区并根据需要将指针传递给数据,可以更好地服务.有些实例,各种回调函数等需要全局数据,但根据经验,这些是例外,而不是规则.
你的问题基本上归结为"我如何正确使用指针和双指针(指向指针到类型的指针)变量的数组.在一个答案中无法完全涵盖主题,因为有远太多的情况和背景,其中一个或另一个可以(或应该)使用和为什么.但是,一些例子将有助于你理解基本的差异.
从指向数组的类型开始(例如char *array[]).通常以该形式将其视为函数参数.声明为变量时,会进行初始化.例如:
char *array[] = { "The quick",
"brown fox",
"jumps over",
"the lazy dog." };
Run Code Online (Sandbox Code Playgroud)
char *array[];由于缺少数组大小,变量声明本身无效[..].当全局使用时,如在您的示例中,编译器将接受声明,但将警告声明假定具有一个元素.
array上面声明的元素是char类型的指针.具体来说,元素是指向声明创建的字符串文字的指针.每个字符串都可以通过arrayas中的相关指针访问array[0], ... array[3].
一个指针指向类型(双指针),正是它的名字所暗示的.它是一个指针,它将指针作为其值.在基本术语中,它是指向另一个指针的指针.它可以通过分配arraylike 的地址来访问上面数组的成员:
char **p = array;
Run Code Online (Sandbox Code Playgroud)
在哪里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 */
}
Run Code Online (Sandbox Code Playgroud)
最上面lines,指向指向char的指针最初NULL用于分配MAXL(128)指针到char.线,然后从读stdin入buf,每次成功读取后,存储被分配给容纳的内容物buf,将所得起始地址的存储器中的每个块被分配给每个指针line[index],其中index是0-127,并且在的增量index到128,index被重新分配,以提供额外指针和继续阅读.
是什么让主题大于可以在任何一个答案中处理的主题是一个指针数组或指向类型指针的指针可以是任何一个type.(int,struct或者作为不同类型的结构的成员,或者function等等......)它们可以在目录列表(例如)的返回中使用链接列表opendir,或者以任何其他方式使用.它们可以静态初始化,动态分配,作为函数参数传递等等......有太多不同的上下文来覆盖它们.但是在所有情况下,他们都会遵循这里和其他答案中的一般规则,并且在StackOverflow上有1000多个答案.
我将以一个简短的示例结束,您可以使用它来查看数组和双指针的不同基本用法.我在源代码中提供了其他评论.这仅提供了一些不同的基本用法以及静态声明和动态分配:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您有任何疑问,请告诉我.这是一个规模相对较小的大型主题,可以在很多不同的方式和不同的环境中应用.
我的教授写道,
**array就像*array[]
在某些情况下也是如此,在其他情况下则不然.
如果在函数中用作参数,
void foo(int **array) {}
Run Code Online (Sandbox Code Playgroud)
是相同的
void foo(int *array[]) {}
Run Code Online (Sandbox Code Playgroud)
当声明为变量时
int **array;
Run Code Online (Sandbox Code Playgroud)
是不一样的
int *array[];
Run Code Online (Sandbox Code Playgroud)
免责声明:这绝不是一份详尽的清单,列出了它们的相同之处和不同之处.