【问题标题】:Returning structure from function从函数返回结构
【发布时间】:2014-07-17 11:14:35
【问题描述】:

下面是我从函数返回结构的代码。可能是这个问题非常基本,但我不清楚为什么我在struct emp putinfo (){ 这一行写emp。我不清楚为什么我需要写结构名称?因为在函数内部,我将结构定义为struct emp t;。具体原因是什么?

#include <stdio.h>


struct emp {

    int number;
    char name [200];

};


void print (struct emp team){

    printf ("Details of employee %d %s", team.number, team.name );

}

struct emp putinfo (){

    struct emp t;
    printf ("Enter number"); scanf ("%d", &t.number);
    printf ("Enter name"); scanf ("%s", &t.name);
    return t;
}


int main (){

    struct emp test;
    test = putinfo ();
    print (test);
    return 0;

}

【问题讨论】:

  • scanf ("%d", &amp;t.name); --> scanf ("%199s", t.name);
  • 通常你不想将一个结构传递给一个函数,或者从一个函数返回一个结构。相反,您希望将 指针 传递/返回给 struc。否则你最终会到处复制。

标签: c function structure


【解决方案1】:

struct emp实际上是你在C中寻址结构的名称。你可以typedef它,然后你只能写emp。它出现在putinfo之前的原因是因为这是返回的按函数键入。struct emp t 只是创建一个emp 类型的新结构并将其分配给t

【讨论】:

    【解决方案2】:

    C 中,您在定义结构时创建的类型的名称是struct structure_name C++ 允许使用这种格式或只是structure_name

    例子:

    struct some_struct{};
    struct some_struct x;   // Variable declaration C, C++ syntax.
    some_struct y;          // Only C++ syntax.
    

    如果您使用C,则必须使用C 语法指定函数的返回值:

    struct some_struct my_function(){}
    

    另一方面,C++ 你可以

    struct some_struct my_function(){}
    

    some_struct my_function(){}
    

    【讨论】:

      【解决方案3】:

      定义您的结构并改用类型定义:

      #include <stdio.h>
      
      
      typedef struct {
      
          int number;
          char name [200];
      
      }emp;
      
      
      void print (emp team){
      
          printf ("Details of employee %d %s", team.number, team.name );
      
      }
      
       emp putinfo (){
      
          emp t;
          printf ("Enter number"); scanf ("%d", &t.number);
          printf ("Enter name"); scanf ("%d", &t.name);
          return t;
      }
      
      
      int main (){
      
          printf("hello\n");
          emp test;
          test = putinfo ();
          print (test);
          return 0;
      
      }
      

      【讨论】:

      • 为什么在大括号后面使用名称emp?这是什么意思?如果我在结构后和大括号后使用 emp 有什么区别?
      【解决方案4】:

      你说得对,这是多余的(乍一看,但见下文),但这就是 C 的工作方式,没有类型推断。这对于每种类型都是相同的(与结构无关):

      succ.c

      unsigned succ(unsigned n) {
          unsigned succ = n + 1;
          return succ;
      }
      

      在这里,您也可以说,没有真正的理由必须指定返回类型。

      所以,现在需要这样做的部分:

      1) 至少在原型中需要它,因为编译器可能无法看到定义,请考虑

      ma​​in.c

      #include <stdio.h>
      
      unsigned succ(unsigned);
      
      int main(void) {
          printf("%u\n", succ(1));
      }
      

      可能已经编译了包含succ 实现的目标文件(您可以通过gcc main.c succ.o 等进行编译)。

      2) 考虑

      long int_to_long(int n) { return n; }
      

      int 被转换为long(如果没有返回类型,编译器就无法知道)。好的,这不适用于结构(它们从不隐式转换),但它是一致的。

      通常,您根本不按值传递结构,而是传递指向它的指针,尤其是当它们很大时。

      最后,关于您的代码的几点说明:

      永远不要在没有scanf 长度的情况下使用%s。总是错的(scanf 怎么知道你提供的数组有多大?),例如

      printf ("Enter name\n"); scanf ("%199s", t.name);
      

      或改用fgets;在生产代码中,您几乎不想使用scanf,因为错误处理很复杂。另请注意我添加的换行符,直到您将换行符写入stdout 之后才会出现要求输入的消息(stdout 通常是行缓冲的,因此通常是终端,(更好的)替代方案是fprintf(stderr, "Enter name: ");,因为stderr 是无缓冲的,所以这个输出不应该真的转到stdout。)。

      一般来说,我建议您在熟悉指针和数组、动态内存分配、错误处理和文件缓冲之前不要编写交互式程序,而是通过命令行参数从用户那里传递信息。您目前知道的太少,无法正确编写交互式程序。

      HTH

      【讨论】:

        猜你喜欢
        • 2015-02-14
        • 1970-01-01
        • 2019-06-02
        • 2020-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多