如何在 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]?的主要内容,如果未能解决你的问题,请参考以下文章

如何从string类型的变量 返回一个char* 类型

如何在c ++中增加字母?

如何在 C 编程中使用 fgets 编写返回文本文件所有内容的函数?

如何在 C++ 中返回本地数组?

如何删除在C中循环中被调用的char图像?

char数组如何存储在C++中?