打印整个结构 C 信息的最有效方法?

Posted

技术标签:

【中文标题】打印整个结构 C 信息的最有效方法?【英文标题】:Most effective way to print the info of a entire structure 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;)你真的想使用哪个? 【参考方案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(), ...

以上是关于打印整个结构 C 信息的最有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

从大型 JSON 文件创建树状结构的最有效方法

将标准化数据提供给报告软件的最有效方法是啥

在 Python 中打印字符串的最有效方法是啥?

在 C# 中存储和比较目录的最有效数据结构是啥?

构建非循环依赖关系的最简单和最有效的数据结构是啥?

确保 char 存在于结构的末尾