如何在 c 中返回 char (*)[6]?
Posted
技术标签:
【中文标题】如何在 c 中返回 char (*)[6]?【英文标题】:How to return char (*)[6] in c? 【发布时间】:2015-04-22 23:56:48 【问题描述】:我想按字母顺序排序字符串数组,它是 c 中的字符数组数组。这是我的函数的主体:-
char (*)[6] sort_strings ( char (*sptr) [6])
//code.
//return a pointer of type char (*)[6].
但是编译器无法识别这种类型的返回类型。它给出的错误是:-
预期的标识符或 '(' 之前的 ')' 标记
那么我如何返回一个 char (*)[6] 类型的指针呢?我心里还有个问题,先看main()
如下:-
int main()
char names[5][6] =
"tom",
"joe",
"adam"
;
char (*result)[6] = sort_strings (names);
//code for printing the result goes here.
return 0;
所以我的下一个问题是,当我调用 sort strings (names)
时,编译器也会给我警告:-
初始化使指针从整数而不进行强制转换
所以我的问题是:-
1.如何从函数中返回char(*)[6]?
2.为什么当我调用这个函数时编译器给我警告?
我正在 Windows 上的代码块上运行此代码。
【问题讨论】:
@Transcendental 是否等同于 char(/*)[6]。我认为这个符号最终会衰减为 char(/*)[6],我在写吗? 请注意,char (*)[6]
不是指向字符串数组的指针。
@Rouftantical 我不太确定,但你为什么不把数组传递给函数,然后在里面排序。真的没有必要返回二维字符数组,除非你想要那样。
@immibis 但它是一个指向 6 个字符数组的指针。
immibis 击败了我,但在测试时我注意到名称 clarke
实际上需要 7 个字符,而不是 6 个字符,因为 NUL 终止符。
【参考方案1】:
函数声明看起来像变量声明,除了变量名被函数名和参数替换。所以:
// asdf is a pointer to an array of 6 chars
char (*asdf)[6];
// sort_strings is a function returning a pointer to an array of 6 chars
// (and with an argument which is a pointer to an array of 6 chars)
char (*sort_strings ( char (*sptr)[6] )) [6];
【讨论】:
请详细说明您的最后一个符号。 在语法方面为什么编译器不接受函数体? 函数声明按照你的建议工作,但编译器给出了同样的错误。请详细解释发生了什么。 哦,对不起!那是我的错!它可以工作,但是如果你能详细解释一下它会更有帮助,它是如何工作的,因为你编写的函数声明工作得很好,但看起来很棘手。 解释很简单:C的语法是这样定义的。【参考方案2】:如果你坚持要对一个包含 6 个字符串的数组进行排序,你可以把它打包成一些 struct
之类的
struct sixstrings_st
char* ptrarr[6];
;
但是,您可能希望对任意数量的字符串进行排序。然后你要么将该数字作为另一个正式参数传递(你也可以有一些其他的约定,比如将数组的大小存储在某个全局中,但这很难看):
void sort_strings (char**arrptr, unsigned siz);
或者你可以使用flexible array members。
顺便说一句,不要重新发明排序,使用qsort(3)
此外,出于可读性目的,您通常不希望使用复杂的类型。使用typedef
,并根据需要定义尽可能多的struct
(可能使用union
-s)。
小心使用数组。在许多情况下(尤其是传递给函数的参数),数组衰减为指针(请注意,处理器通常不会在单个机器指令中一次处理整个数组)。而且一个函数不能真正返回一个数组,只是一个指针(或一些struct
)。
在 C 编程中,通常有函数返回 标量 数据(例如,整数或某个指针)。返回 struct
并不常见(与 C++ 相反,通常返回 class
实例)。当您确实返回 struct
时,您通常希望它“足够小”(否则函数 return 在概念上会复制大量字节)。顺便说一句,一些ABI-s 可能有返回两个标量元素的struct
的特定规则。对于 Linux 上的 x86-64 ABI,带有两个整数或两个指针的 struct
通过两个机器寄存器返回。
通常,函数是返回指针(可能由malloc
获取并填充函数),您应该定义一个约定并记录应该如何处理返回的指针,特别是谁对free
负责它以及如何。 C 编程中的一个常见习惯用法是定义创建函数foo_create
,这些函数分配一个复杂的数据结构struct foo_st
(通常通过为某些struct
调用malloc
以及为其组件的其他创建函数)并返回一个指向它的指针, 并销毁正在销毁此类数据结构的函数 foo_destroy
(通常通过销毁组件然后在作为 struct foo_st*
指针传递的整个结构上调用 free
)。
一般来说,在C中你要避免传递或返回largedata structures(比如bigstruct
-s,数组,union
-s, ...) 到函数和从函数(以避免大量数据被复制,因为 C calling convention 是 call by value)。所以你小心使用指向它们的指针:避免使用memory leaks 和memory corruption。因此,您不会返回排序后的数组,而是返回一些指向它的指针(并且您会记录谁应该销毁该数组,如何以及何时)...阅读C dynamic memory allocation 甚至是garbage collection(至少要了解术语) ,以及 reference counting 等基本技术。
最后,您通常不希望在源代码中硬编码像 6 这样的大小。您应该想要处理任意(但合理)大小的任意字符串数组。如果您需要对尺寸进行硬编码,至少给它一些可读的名称,例如在适当的地方使用#define MY_WEIRD_SIZE 6
和代码MY_WEIRD_SIZE
而不是6...
【讨论】:
是的 char** 可以工作,但为什么我的符号不起作用 因为 C 是这样设计的(因为历史上 C 被设计为接近硬件,并且硬件不会在单个机器指令中处理整个数组)。使用 C++,您可以使用std::array
在结构的情况下,最好返回指向结构的指针。
并非总是如此,C 允许返回 struct
并且有很多有用的案例!
请给我解释一下其他答案以上是关于如何在 c 中返回 char (*)[6]?的主要内容,如果未能解决你的问题,请参考以下文章