问题描述
假设我们有一个字符串数组初始化如下:
char **a = malloc(3 * sizeof(char*)); //edited
a[0]="asd";
a[1]="fghj";
a[2]="klzxc";
我们如何打印此二维数组(3)的第一维?
解决方法
我们如何打印此二维数组(3)的第一维?
您必须跟踪在单独变量中分配的元素数量:
size_t num_elements = 3;
char **a = malloc( sizeof *a * num_elements );
if ( a )
{
a[0] = "asd"; // NOTE: these lines store the addresses of the string
a[1] = "fghj"; // literals in a[0],a[1],and a[2] - you are not copying
a[2] = "klzxc"; // the *contents* of each string,just its address
}
...
for ( size_t i; i < num_elements; i++ )
printf( "a[%zu] = %s\n",i,a[i] );
无论类型如何,指针都指向(存储)单个对象。该单个对象可能是更大对象序列中的第一个对象,但是无法从指针值本身确定该对象。如果您具有以下条件:
char ** char * char
+---+ +---+ +---+---+---+---+
a:| | ---> | | a[0] -----> |'a'|'s'|'d'| 0 |
+---+ +---+ +---+---+---+---+
| | a[1] ---+
+---+ | +---+---+---+---+---+
| | a[2] -+ +-> |'f'|'g'|'h'|'j'| 0 |
+---+ | +---+---+---+---+---+
|
| +---+---+---+---+---+---+
+---> |'k'|'l'|'z'|'x'|'c'| 0 |
+---+---+---+---+---+---+
您无法从a
本身知道它指向3个对象中的第一个;您无法从每个a[i]
本身知道它指向一系列char
对象。该信息必须单独跟踪。对于a
,我们有一个单独的变量num_elements
,用于跟踪a
中元素的可能情况。对于每个a[i]
,我们都有字符串终止符来告诉我们每个字符串有多长。
我们如何打印此二维数组(3)的第一维?
之前的几点:
准确地说,char **a
不是2D数组,它是指向char
的指针。
使用此内存分配的一种更安全的方法是使用取消引用的指针而不是类型,此方法有助于代码的维护:
char **a = malloc(sizeof *a * 3);
要注意的另一件事是,分配给这些指针的字符串文字是只读的,无法更改。
要回答您的问题:
要知道第一个维度 ie 分配的指针数,您需要牢记它,可能将其存储起来,没有可移植的方法来检索指针之后分配的指针数。事实。
但是,有一些非便携式方法可以做到这一点:
size_t size = _msize(a)/sizeof *a; //Windows
size_t size = malloc_usable_size(a)/sizeof *a; //Linux
size_t size = malloc_size(a)/sizeof *a; //Mac OS
当函数返回分配的字节数时,将其返回值除以指针的大小即可获取指针的实际数量。
如果您需要实际的可编辑char数组:
如果要具有一个可以实际编辑和更改的字符数组,则还必须为这三个指针中的每一个分配内存。
例如
for(int i = 0; i < 3; i++)
a[i] = malloc(4) //for char arrays of 3 chars + null byte
此后,要分配字符串,您需要使用类似strcpy
或最好使用memcpy
之类的东西。
例如
memcpy(a[0],"asd",4); //copies "asd" to a[0]