C结构:打印字符串成员会产生奇怪的结果

时间:2017-02-19 05:04:15

标签: c string struct

我独立学习C.我有四个成员结构如下:

#define aSize 10
struct Students {
     char lastName[aSize];
     char firstName[aSize];
     int age; 
     int grade;
 }

我有两个独立的函数(在main.c文件中):

void pasteInfo_1(struct Students S1) {}

void printStudents(struct Students S1) {}

pasteInfo()使用strcpy()和赋值为成员分配值;然后printStudents()打印存储在成员中的值。当我编译文件时:

#in makefile
CFLAGS = -lm -o -Wall
gcc main.c $(CFLAGS) main

它编译没有错误。但是,当我调用可执行文件时,它会打印一些非常奇怪的字符,看起来像二进制/汇编。有什么建议?以下是各项功能。

void pasteInfo_1(struct Students S1) {
     strcpy(S1.lastName, "Effinger");
 }

这是printStudents:

void printStudents(struct Students S1) {
     printf("%s\n",S1.lastName);
}

函数调用main:

int main() {
     struct Students S1;
     pasteInfo_1(S1);
     printStudents(S1);
 }

回复:修改。 添加user3629249建议的更改后,我收到以下错误:

main.c:6:23:警告:在此定义或声明之外,将无法在参数列表中声明的'struct Students'  void pasteInfo(struct Students * pS1);                        ^ ~~~~~~~ main.c:7:27:警告:在此定义或声明之外,在参数列表中声明的'struct Studens'将不可见  void printStudents(struct Studens S1);                            ^ ~~~~~~ main.c:在函数'main'中: main.c:22:14:警告:从不兼容的指针类型[-Wincompatible-pointer-types]传递'pasteInfo'的参数1    pasteInfo(& S1);               ^ main.c:6:6:注意:预期'struct Students *'但是参数类型为'struct Students *'  void pasteInfo(struct Students * pS1);       ^ ~~~~~~~~ main.c:23:17:错误:形式参数1的类型不完整    printStudents(S1);                  ^〜 main.c:顶级: main.c:26:6:错误:'pasteInfo'的冲突类型  void pasteInfo(struct Students * pS1)       ^ ~~~~~~~~ main.c:6:6:注意:之前的'pasteInfo'声明就在这里  void pasteInfo(struct Students * pS1);       ^ ~~~~~~~~ main.c:32:6:错误:'printStudents'的冲突类型  void printStudents(struct Students S1)       ^ ~~~~~~~~~~~~ main.c:7:6:注意:之前的'printStudents'声明就在这里  void printStudents(struct Studens S1);       ^ ~~~~~~~~~~~~

3 个答案:

答案 0 :(得分:3)

  

我独立学习C。

这是什么意思?你在读书吗?如果是这样,哪本书?

请记住,通过错误的试错来学习C是危险的;你最有可能最终学到的东西是微妙的,可能是危险的,与C不同的东西,哪种药物最能解决你给自己带来的麻烦...

您遇到的问题是由于按值传递。调用函数时,会生成结构的副本,并且该副本是您在被调用函数中修改的副本。因此,调用者(main)中的原始结构未经修改,并且通过从未初始化的对象打印,您将调用未定义的行为。作为指南,我可以告诉您,将返回修改后的结构回到main然后将该返回值分配回S1是安全的,前提是您正在使用符合C99标准的编译器(在这个时代并没有太多问题。)

这是误入歧途的学习所带来的危险;你会遇到很多未定义的行为(以及实现定义的行为),这些行为会因系统而异,并且可能在当时没有意义......你最好通过阅读一本体面的书来避免UB和IB作为K& R2E,并在你偶然发现它们时进行练习。

答案 1 :(得分:0)

当被调用函数计划(直接)更改调用函数中的任何内容时,将该项的地址传递给被调用函数。 I.E.

int main( void ) 
{
    struct Students S1;
    pasteInfo_1( &S1 );   // <-- passing pointer to struct
    printStudents( S1 );
}

然后修改pasteInfo_1()`函数以期望指针

void pasteInfo_1( struct Students * pS1 ) 
{
    strcpy( pS1->lastName, "Effinger" );
}

注意使用支撑的垂直对齐和使用适当的水平间距。

垂直对齐和水平间距的目的是使代码更具可读性。

答案 2 :(得分:-1)

解决了!这是工作代码: (特别感谢user3629249和Seb的建议)

'#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>

 struct Students
 {
     char lastName[8];
     char firstName[6];
     int age;
     int grade;
 };

 void pasteInfo(struct Students *S1);
 void printStudnets(struct Students S1);

 int main(void)
 {

     struct Students S1;
     pasteInfo( &S1 );
     printStudents( S1 );
 }
 void pasteInfo(struct Students *S1)
 {
     strcpy(S1->lastName, "Effinger");
 }
 void printStudent(struct Students S1)
 {
      printf("%s\n",S1.lastName);
 }