如何在 C 语言中返回一个指针
Posted
技术标签:
【中文标题】如何在 C 语言中返回一个指针【英文标题】:How to return a pointer in C Language 【发布时间】:2017-08-08 13:02:02 【问题描述】:我有一个返回指针的函数,我正在让它计算给定数字的阶乘。
这是我无法更改的骨架代码
#include<stdio.h>
#include<string.h>
//Read only region start
char* factorial (int input1)
//Read only region end
//Write code here
我写的代码是:
我也试试这个代码
#include<stdio.h>
#include<string.h>
//Read only region start
char* factorial (int input1)
//Read only region end
//Write code here
char fact=1;
while(input1!=0)
fact = fact * input1;
input1--;
return fact;
左边是问题,右边是我正在写的代码。 它抛出的错误是“Segmentation fault”
该程序不需要main()
函数,因为mettl 在后端使用它来调用函数并评估结果。
【问题讨论】:
不要发布您的代码图片,而是直接复制粘贴到您的问题中char *fact=1;
声明了一个指针并将指针(地址)设置为 1。因此,对 *fact+input
的引用将是一个段错误,因为您试图访问内存中的地址 1
。您需要分配一个有效的地址放入fact
,然后才能正确引用。
将您的代码作为文本发布会更好。屏幕截图很难阅读,也无法从中复制/粘贴代码。您没有函数指针,而且您似乎也不了解指针在取消引用时是如何工作的。你的指针指向一个无效的地址,然后你写在那里,所以这是未定义的行为,但这种情况通常会导致崩溃。
您的新代码正在生成一个整数,但随后将其作为char *
返回。如果该函数的调用者试图将其作为指针引用,那么您会得到一个段错误。您的函数没有返回某个地址。目前还不清楚它应该具体返回什么。顺便说一句,它不是函数指针。这是一个返回指向char
的指针的函数。它返回的指针需要指向调用者可用的有效内存地址。你熟悉 C 的工作原理吗? char fact;
将 fact
声明为单个字节,取值范围 -128 到 127。
这 (***.com/a/44053522/920069) 回答了您的问题,但它是用 C++ 编写的。我在这里将其改编为 C:ideone.com/tER5R3 如果有帮助,请给他点赞。
【参考方案1】:
我修改了你的代码,下面是它的正确版本:
unsigned int factorial (int input1)
unsigned int res = 1;
while(input1 > 1)
res = res * input1;
input1--;
return res;
您的错误是返回指针 (char *)
而不是简单的字符(单字节值)。
我还将char
更改为unsigned int
。为什么?
unsigned
:因为您似乎希望您的结果是肯定的,否则您的 input1--
循环将无法工作。因此,无符号允许您在达到数据类型限制之前获得更大的结果集(有符号字符的最大值为 127,无符号字符的最大值为 255)。
int
:因为在幕后(在汇编代码中)传递到堆栈和 CPU 寄存器的数据大小是一个 int。 ASM 指令告诉只使用寄存器的一个字节(在 4 或 8 个字节中,取决于 x32 或 x64)。但是使用 byte 而不是 int 并没有任何性能提升。那么,如果它可以覆盖更大的结果集,为什么不使用 int 呢? :-)
我还在 > 1 条件下停止了循环,因为再运行一次迭代以进行 x1
乘法是没有用的。这是一个真正的坏蛋优化... 笑话 ;-))
更新:
根据您的 cmets,您无法更改函数定义,因此此代码将通过将结果作为字符串返回 (char *
) 来工作:
char* factorial (int input1)
unsigned int res = 1;
char *str;
while(input1 > 1)
res = res * input1;
input1--;
str = malloc(32);
sprintf(str, "%u", res);
return str;
请注意,它分配了一个缓冲区来存储结果(即使在 64 位上,32 也应该没问题......)。您可能希望在使用后free()
缓冲区以避免内存泄漏。
【讨论】:
老兄,我无法更改这个“char* factorial (int input1)”,它是从平台提供商预编码的。 C 中根本没有“字节”乘法。所有排名较低的操作数在乘法之前提升为int
或unsigned int
。
@Antti:正如我所说,“传递到堆栈和 CPU 寄存器的数据大小是一个 int”。发生的情况是在那之后您仍然有字节级操作,例如:mov %al,-0x3(%rbp)
或 movsbl %al,%eax
其中 AL 是寄存器中最弱的字节。
factorial(100) 不适合 int。以上是关于如何在 C 语言中返回一个指针的主要内容,如果未能解决你的问题,请参考以下文章