【问题标题】:Most effective way to print the info of a entire structure C?打印整个结构 C 信息的最有效方法?
【发布时间】:2021-08-02 18:57:16
【问题描述】:

我想知道是否有更有效的方法(更少的行,更少的内存)来打印字符串中包含的信息。我在用函数参数循环思考。例如,如果您需要打印 100 个学生的信息(姓名、组和出生日期),我想有一个更好的方法,将 printstudent( studentn) 写一百次。 问题是我不知道如何创建一个循环,所以从 student1 到 student100 调用。我不能称它为 student[i] 还是可以?

我愿意接受任何建议或想法谢谢!

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

void printstudents(struct st student);

struct st {
  char familia[1000];
  char imia[1000];
  char otchestvo[1000];
  int gruppa;
  int grozhdenia;
};

int main() {

  struct st student1;
  struct st student2;
  struct st student3;

  //Информация студентов:

  strcpy(student1.familia, "Putin");
  strcpy(student1.imia, "Vladimir");
  strcpy(student1.otchestvo, "Vladimirovich");
  student1.gruppa = 40040;
  student1.grozhdenia = 1952;

  strcpy(student2.familia, "Gordon");
  strcpy(student2.imia, "Dymitro");
  strcpy(student2.otchestvo, "Aleksandrovich");
  student2.gruppa = 50050;
  student2.grozhdenia = 1953;

  strcpy(student3.familia, "Emelianenko");
  strcpy(student3.imia, "Fedor");
  strcpy(student3.otchestvo, "Olegovich");
  student3.gruppa = 60060;
  student3.grozhdenia = 1950;

  printstudents(student1);
  printstudents(student2);
  printstudents(student3);

  return 0;
}

void printstudents(struct st student) {
  printf("Student: %s %s %s, %d, %d \n", student.imia, student.otchestvo,
         student.familia, student.gruppa, student.grozhdenia);
}

【问题讨论】:

  • 通常你会为此使用一个数组。
  • 你应该让printstudents接受一个指向对象的指针——否则C会在你调用函数时复制结构。
  • 是的,您可以声明struct st student[101];(不是student[100],因为索引从零开始)使用student[1]student[100]
  • @MikeCAT 如果 OP 有 100 名学生,他们应该只使用 student[0]student[99] - 无需为额外的学生分配内存就可以使用非标准的基于 1 的索引。
  • 你在标题和标签中说“C”,但你的代码是 C++(由于额外的#include &lt;iostream&gt;using namespace std;)你真的想使用哪个?

标签: c data-structures struct


【解决方案1】:
#include <stdio.h>
#include <string.h>

struct st;
void printstudents(const struct st *student);

struct st {
        char familia[1000];
        char imia[1000];
        char otchestvo[1000];
        int gruppa;
        int grozhdenia;
};

int
main(void)
{
        struct st student[3] = {
                { "Putin", "Vladimir", "Vladimirovich", 40040, 1952 },
                { "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953 },
                { "Emelianenko", "Fedor", "Olegovich", 60060, 1950}
        };
        for( int i = 0; i < 3; i ++ ){
                printstudents(student + i);
        }

        return 0;
}

void
printstudents(const struct st * student)
{
        printf("Student: %s %s %s, %d, %d\n",
                student->imia,
                student->otchestvo,
                student->familia,
                student->gruppa,
                student->grozhdenia
        );
}

【讨论】:

    【解决方案2】:

    如果我们谈论的是执行速度和内存使用方面的实际性能,那么这里是最明显的瓶颈:

    • printf 的格式字符串解析很慢。使用重复的puts 调用可能比使用单个printf 快很多。

    • 显然,您不应该将庞大的结构按值传递给函数。 struct st student 会导致一个几 kb 的大结构被复制到堆栈中,以防您的编译器无法内联函数调用。根据经验,永远不要按值传递结构。使用指针。

    • 您制作常量字符串文字的硬拷贝。您可以只使用const char* familia,然后使用student2.familia = "Gordon";,这比strcpy 快得多。不利的一面是,如果您这样做,您只能获得只读内存。

    【讨论】:

      【解决方案3】:

      这是对代码的修改,以使用由 3 个学生结构组成的静态堆栈分配数组(以及用于初始化学生的辅助函数)。

      您需要阅读指针的工作原理才能理解它,但那是 C 适合您。

      #include <stdio.h>
      #include <string.h>
      
      struct st {
        char familia[1000];
        char imia[1000];
        char otchestvo[1000];
        int gruppa;
        int grozhdenia;
      };
      
      static void assign_student(struct st *student, const char *familia, const char *imia, const char *otchestvo, int gruppa, int grozhdenia) {
        // TODO: use strncpy
        strcpy(student->familia, familia);
        strcpy(student->imia, imia);
        strcpy(student->otchestvo, otchestvo);
        student->gruppa = gruppa;
        student->grozhdenia = grozhdenia;
      }
      
      static void print_student(struct st *student) {
        printf("Student: %s %s %s, %d, %d \n", student->imia, student->otchestvo,
               student->familia, student->gruppa, student->grozhdenia);
      }
      
      int main() {
        struct st students[3];
        assign_student(&students[0], "Putin", "Vladimir", "Vladimirovich", 40040, 1952);
        assign_student(&students[1], "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953);
        assign_student(&students[2], "Emelianenko", "Fedor", "Olegovich", 60060, 1950);
        for (int i = 0; i < 3; i++) {
          print_student(&students[i]);
        }
        return 0;
      }
      

      【讨论】:

      • 对于像char familia[1000]; 这样的大成员,用TODO: use strncpy 填充整个数组是有问题的。其他方法可用于检测/防止过度填充,可能采用strncat(), snprintf(), ...
      猜你喜欢
      • 2012-10-14
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 2022-06-13
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多