什么是 char **text = (char **) malloc(n * sizeof(char*));做?
What does char **text = (char **) malloc(n * sizeof(char*)); does?
我刚开始编程,我不知道这是什么意思..
我尽力了..
我知道它的动态内存分配,但不知道所有这些(星星)是什么意思。
有人可以向我解释一下,每种类型是什么吗?
这是代码:
char **text = (char **) malloc(n * sizeof(char*));
text[i] = (char *) malloc(MAX_LENG);
代码分配(动态)内存以保存 n
个字符串。这些字符串中的每一个都具有最大长度 MAX_LENG - 1
.
我假设完整的原始代码是:
char **text = (char **) malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
text[i] = (char *) malloc(MAX_LENG);
或没有不必要的转换:
char **text = malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
text[i] = malloc(MAX_LENG);
所以第一行,即
char **text = malloc(n * sizeof(char*));
会给你一个指向内存区域的指针,其中包含 n
个指向字符的指针
循环,即
for (int i = 0; i < n; ++i)
text[i] = malloc(MAX_LENG);
然后使这些 n
指针中的每一个都指向具有 MAX_LENG
个字符的内存区域。
看起来像:
所以在这之后你有 n
个字符串的记忆并且可以像这样使用它们:
strcpy(text[0], "HELLO"); // First string is "Hello"
strcpy(text[1], "WORLD"); // Second string is "World"
之后它看起来像:
您可以像这样访问各个字符
char c = text[1][4]; // c now holds the character 'D' from the string "WORLD"
一个简单的解释可以看下面的方式。假设您有一个指向字符串文字的指针数组。例如
char * s[] = { "Hello ", "World!" };
在极少数情况下,表达式中使用的数组指示符被转换为指向其第一个元素的指针。所以在大多数情况下,数组指示符 s
被转换为类型 char **
的指针。也就是说它是一个指向 char *
.
类型对象的指针
例如
char **p = s;
取消引用指针,您将获得数组的第一个元素,该元素的类型又是 char *
。例如
#include <stdio.h>
int main( void )
{
enum { N = 2 };
char * s[N] = { "Hello ", "World!" };
for ( char **p = s; p != s + N; ++p )
{
printf( "%s", *p );
}
putchar( '\n' );
return 0;
}
程序输出为
Hello World!
现在假设你想动态分配数组。该数组具有 N
个类型为 char *
的元素。
所以你需要写出表达式
malloc( N * sizeof( char * ) )
函数调用 return 指向已分配内存范围开始的指针,其中将有类型 char *
的第一个元素。那就是函数 return 是一个类型为 void *
的指针,它可能指向动态分配数组的第一个元素。
所以你需要写
char **p = malloc( N * sizeof( char * ) );
或
char **p = ( char ** )malloc( N * sizeof( char * ) );
类似于上面的声明
char **p = s;
其他答案解释了它的作用,但我想关注一个小细节。
char **text = malloc(n * sizeof(char*));
在 sizeof
中使用类型而不是对象被认为是一种不好的做法。为什么?如果更改对象的类型,则需要更改旧类型的所有可能外观。如果您在 sizeof 中使用该对象 - 每个 sizeof 都将被正确计算而无需更改代码。
char **text = malloc(n * sizeof(*text));
我刚开始编程,我不知道这是什么意思..
我尽力了..
我知道它的动态内存分配,但不知道所有这些(星星)是什么意思。 有人可以向我解释一下,每种类型是什么吗? 这是代码:
char **text = (char **) malloc(n * sizeof(char*));
text[i] = (char *) malloc(MAX_LENG);
代码分配(动态)内存以保存 n
个字符串。这些字符串中的每一个都具有最大长度 MAX_LENG - 1
.
我假设完整的原始代码是:
char **text = (char **) malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
text[i] = (char *) malloc(MAX_LENG);
或没有不必要的转换:
char **text = malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
text[i] = malloc(MAX_LENG);
所以第一行,即
char **text = malloc(n * sizeof(char*));
会给你一个指向内存区域的指针,其中包含 n
个指向字符的指针
循环,即
for (int i = 0; i < n; ++i)
text[i] = malloc(MAX_LENG);
然后使这些 n
指针中的每一个都指向具有 MAX_LENG
个字符的内存区域。
看起来像:
所以在这之后你有 n
个字符串的记忆并且可以像这样使用它们:
strcpy(text[0], "HELLO"); // First string is "Hello"
strcpy(text[1], "WORLD"); // Second string is "World"
之后它看起来像:
您可以像这样访问各个字符
char c = text[1][4]; // c now holds the character 'D' from the string "WORLD"
一个简单的解释可以看下面的方式。假设您有一个指向字符串文字的指针数组。例如
char * s[] = { "Hello ", "World!" };
在极少数情况下,表达式中使用的数组指示符被转换为指向其第一个元素的指针。所以在大多数情况下,数组指示符 s
被转换为类型 char **
的指针。也就是说它是一个指向 char *
.
例如
char **p = s;
取消引用指针,您将获得数组的第一个元素,该元素的类型又是 char *
。例如
#include <stdio.h>
int main( void )
{
enum { N = 2 };
char * s[N] = { "Hello ", "World!" };
for ( char **p = s; p != s + N; ++p )
{
printf( "%s", *p );
}
putchar( '\n' );
return 0;
}
程序输出为
Hello World!
现在假设你想动态分配数组。该数组具有 N
个类型为 char *
的元素。
所以你需要写出表达式
malloc( N * sizeof( char * ) )
函数调用 return 指向已分配内存范围开始的指针,其中将有类型 char *
的第一个元素。那就是函数 return 是一个类型为 void *
的指针,它可能指向动态分配数组的第一个元素。
所以你需要写
char **p = malloc( N * sizeof( char * ) );
或
char **p = ( char ** )malloc( N * sizeof( char * ) );
类似于上面的声明
char **p = s;
其他答案解释了它的作用,但我想关注一个小细节。
char **text = malloc(n * sizeof(char*));
在 sizeof
中使用类型而不是对象被认为是一种不好的做法。为什么?如果更改对象的类型,则需要更改旧类型的所有可能外观。如果您在 sizeof 中使用该对象 - 每个 sizeof 都将被正确计算而无需更改代码。
char **text = malloc(n * sizeof(*text));