我有一个二维数组,其中第一个维度具有可变长度但第二个维度是固定的。现在在函数调用中,我可以执行char foo[][3]
之类的操作,但struct
中的相应定义是什么?
因此在示例代码中我希望它能够在一行中打印每个字符串,但正如预期的那样,它将存储的指针视为一维数组。
#include <stdlib.h>
#include <stdio.h>
struct payload_s {
size_t length;
char *text;
};
typedef struct payload_s payload;
static char some_text[4][3] = {"Ab", "Cd", "Ef", "Gh"};
payload* create_payload(char *text, size_t length)
{
payload *p = malloc(sizeof *p);
p->text = text;
p->length = length;
return p;
}
int main()
{
payload *p = create_payload(some_text, 4);
for (size_t i = 0; i < p->length; ++i)
printf("%zu: %s\n", i, &p->text[i]);
}
由于警告,我主要注意到了这一点:
strut.c: In function ‘main’:
strut.c:23:33: warning: passing argument 1 of ‘create_payload’ from incompatible pointer type [-Wincompatible-pointer-types]
payload *p = create_payload(some_text, 4);
^~~~~~~~~
strut.c:13:10: note: expected ‘char *’ but argument is of type ‘char (*)[3]’
payload* create_payload(char *text, size_t length)
^~~~~~~~~~~~~~
当函数实际定义为payload* create_payload(char text[][3], size_t length)
时,我可以摆脱这个警告,但之后会有几行警告并且行为没有改变:
strut.c: In function ‘create_payload’:
strut.c:16:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
p->text = text;
^
是唯一的手动递增指针的方法是每个值的长度吗?
答案 0 :(得分:1)
使用:
char (*text)[3];
而不是:
char *
因为你想要的是指向你的2D数组的指针,而不是指向单char
的指针。阅读C pointer to two dimensional array中的更多内容。
当然,建议使用定义或类似的维度,而不是硬编码3,就像我的例子一样。
最小。例如:
#include <stdlib.h>
#include <stdio.h>
#define M 3
struct payload_s {
size_t length;
char (*text)[M]; // change the member!
};
typedef struct payload_s payload;
// not need for null terminators in the strings,
// it will be placed automatically
static char some_text[4][M] = {"Ab", "Cd", "Ef", "Gh"};
// change the prototype as well
payload* create_payload(char (*text)[M], size_t length)
{
payload *p = malloc(sizeof *p);
p->text = text;
p->length = length;
return p;
}
int main()
{
payload *p = create_payload(some_text, 4);
for (size_t i = 0; i < p->length; ++i)
// no need to print the address now
// also 'zu' should be used for 'size_t'
printf("%zu: %s\n", i, p->text[i]);
}
输出:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
0: Ab
1: Cd
2: Ef
3: Gh
PS - 检查malloc()
返回的内容,看看内存是否实际分配(当然是真实代码,而不是最小分数)。
答案 1 :(得分:1)
这一行:
static char some_text[4][3] = {"Ab\0", "Cd\0", "Ef\0", "Gh\0"};
尝试在每个条目中初始化一个3个字节的数组,每个条目中的值为4个字节。
注意:&#34; AB \ 0&#34;是4个字节,因为声明一个char数组总是将一个NUL字节附加到数组的末尾。
推荐:
static char some_text[4][3] = {"Ab", "Cd", "Ef", "Gh"};
对printf()
的调用包含几个错误,编译器应该告诉你这些错误。
字段:char *text;
实际上指向2D数组,因此应该相应地声明。
需要对malloc()
的调用执行错误检查。
这是代码的一个版本,将应用所有(合理的)更正。
#include <stdlib.h>
#include <stdio.h>
struct payload_s
{
size_t length;
char **text;
};
static char *some_text[] = {"Ab", "Cd", "Ef", "Gh"};
struct payload_s* create_payload(char **text, size_t length)
{
payload *p = malloc(sizeof (struct payload_s));
if( !p )
{
perror( "malloc for instance of payload failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
p->text = text;
p->length = length;
return p;
}
int main( void )
{
//payload *p = create_payload(some_text, 4);
payload *p = create_payload(some_text, sizeof(some_text) / sizeof( *some_text ) );
for (size_t i = 0; i < p->length; ++i)
printf("%lu: %s\n", i, p->text[i]);
}
上述代码的结果是:
0: Ab
1: Cd
2: Ef
3: Gh
答案 2 :(得分:0)
您使用的是不兼容的指针,这些指针无法相互隐式转换。
字符数组some_text
声明为
static char some_text[4][3] = {"Ab\0", "Cd\0", "Ef\0", "Gh\0"};
当它在表达式中用作例如用作参数时,它被隐式转换为指向其第一个元素的指针,并且具有类型char ( * )[3]
。它与char *
类型的指针不同。
看起来你需要一个具有灵活数组的结构。
这是一个演示程序,展示了如何使用这种结构。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
struct payload_s
{
size_t length;
char text[][N];
};
struct payload_s * create_payload( char( *text )[N], size_t length )
{
struct payload_s *p = malloc( sizeof( struct payload_s ) +
length * sizeof( char[N] ) );
p->length = length;
for ( size_t i = 0; i < length; i++ ) strcpy( p->text[i], text[i] );
return p;
}
void free_payload( struct payload_s *p )
{
free( p );
}
int main(void)
{
char some_text[4][N] = {"Ab", "Cd", "Ef", "Gh"};
char another_text[5][N] = {"Bb", "Dd", "Ff", "Hh", "Jj"};
struct payload_s *p1 = create_payload( some_text,
sizeof( some_text ) / sizeof( *some_text ) );
struct payload_s *p2 = create_payload( another_text,
sizeof( another_text ) / sizeof( *another_text ) );
for ( size_t i = 0; i < p1->length; i++ )
{
printf( "%s ", p1->text[i] );
}
printf( "\n" );
for ( size_t i = 0; i < p2->length; i++ )
{
printf( "%s ", p2->text[i] );
}
printf( "\n" );
free_payload( p2 );
free_payload( p1 );
return 0;
}
它的输出是
Ab Cd Ef Gh
Bb Dd Ff Hh Jj