如何在 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 中根本没有“字节”乘法。所有排名较低的操作数在乘法之前提升为intunsigned int @Antti:正如我所说,“传递到堆栈和 CPU 寄存器的数据大小是一个 int”。发生的情况是在那之后您仍然有字节级操作,例如:mov %al,-0x3(%rbp)movsbl %al,%eax 其中 AL 是寄存器中最弱的字节。 factorial(100) 不适合 int。

以上是关于如何在 C 语言中返回一个指针的主要内容,如果未能解决你的问题,请参考以下文章

c语言中如何一个函数的多次调用

C语言函数如何return数组?

C语言 如何给指针数组划分动态存储空间

C语言 如何通过文件指针获得文件名?

C语言函数中如何返回一个结构体类型

C 从函数返回指针