C中未声明的论点

时间:2012-09-08 17:21:46

标签: c arguments undeclared-identifier

我正在尝试用C编译我的程序,这些是我得到的错误: (请注意我是这种语言的初学者。)

Excer3.c:在函数`addstudent'中:

Excer3.c:50: error: `student' undeclared (first use in this function)
Excer3.c:50: error: (Each undeclared identifier is reported only once
Excer3.c:50: error: for each function it appears in.)
Excer3.c:50: error: parse error before "newS"
Excer3.c:50: error: `newS' undeclared (first use in this function)
Excer3.c:50: error: parse error before ')' token
Excer3.c:52: error: `studentName' undeclared (first use in this function)
Excer3.c: At top level:
Excer3.c:59: error: parse error before '*' token
Excer3.c: In function `readdb':
Excer3.c:70: error: `students' undeclared (first use in this function)
Excer3.c:70: warning: passing arg 2 of `addstudent' makes integer from pointer without                 a cast

我的代码看起来像这样。该函数无法识别它给出的参数。 :

#include <stdio.h>

struct student {
int studentnumber;
char* Name;
struct student* next;
};

struct teacher {
int teachernumber;
char* Name;
struct teacher* next;
};

struct course {
struct teacher teachers[5];
struct student students[50];
int semesternumber;
struct course* next;
};

int readline(char s[],int lim)
{
  int c, i;
  for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
    s[i] = c;
  if (c == '\n') {
    s[i] = c;
    ++i;
  }
  s[i] = '\0';
  return i;
}

int addstudent (struct student* prev, int studentnumber, char* studentname)
{
if (!(prev==NULL))
  student newS = (student*)malloc(sizeof(student));
  newS->studentnumber = studentnumber;
  newS->firstname = strdup(studentName);
  newS->next = NULL;
  prev->next=newS;

  return 1;
}

int readdb(student* students)
{
char line[200];
int* studentnumber,coursenumber,teachernumber,semesternumber;
char studentname[100],teachername[100],coursename[100];

while(readline(line,200) > 0)
{
if(sscanf(line, "S %d %s", &studentnumber, studentname)==2)
{
 printf("Student. \n\tStudent number: %d, \n\tFirst name: %s\n", studentnumber,  
studentname);
 addstudent(students,&studentnumber,studentname);
 }
else if(sscanf(line, "C %d %s %d", &coursenumber, coursename , &semesternumber)==3)
   printf("Course. \n\tCourse number: %d \n\tCourse name: %s \n\tSemester: %d\n",   
coursenumber, coursename, semesternumber);
else if(sscanf(line, "E %d %d", &studentnumber, &coursenumber)==2)
printf("Enrolment. \n\tStudent number: %d, \n\tCourse number: %d\n", studentnumber, 
coursenumber);
else if(sscanf(line, "T %d %s", &teachernumber, teachername)==2)
 printf("Teacher. \n\tTeacher number: %d, \n\tFirst name: %s\n", teachernumber,  
teachername);
else if(sscanf(line, "A %d %s", &teachernumber, &coursenumber)==2)
 printf("Assignment. \n\tTeacher number: %d, \n\tCourse number: %d\n", teachernumber,
coursenumber);
}

}


int main () 
{
struct student* students = NULL;

readdb(&students);
return 0;

}

3 个答案:

答案 0 :(得分:3)

您使用的是student而不是struct student如果您只想使用student,则需要在代码中使用typedef struct student student;

答案 1 :(得分:1)

addstudent中,您声明

student newS = (student*)malloc(sizeof(student));

那应该是struct student newS

答案 2 :(得分:1)

现有答案是正确的:student目前不是程序中的类型名称,但struct student是。你已经正确使用了这个,所以只需要保持一致。

冒着偏离代码审核领域的风险,addstudent仍然无法做到你想做的事。

int addstudent (struct student* prev, int studentnumber, char* studentname)
{
    if (!(prev==NULL))
        student newS = (student*)malloc(sizeof(student));
    newS->studentnumber = studentnumber;
    newS->firstname = strdup(studentName);
    newS->next = NULL;
    prev->next=newS;

    return 1;
}

所以这是试图附加到链表的末尾,这很好,但是有一些错误:

  • newS声明应为struct student *newS = malloc(sizeof(*newS));

    1. 我们修复了编译器抱怨的结构名称
    2. malloc返回一个指针,因此newS也必须是指针
    3. p = malloc(sizeof(*p))是一种常见的习惯用法,可以在将来更改p的类型时避免错误,但忘记编辑sizeof表达式
  • 您目前正在if语句的范围内声明newS - 这意味着引用newS的以下行将无法编译,因为他们看不到那个变数。我们可以使用大括号扩展范围:if (prev) { ... } return 1;

  • newS->next 始终设置为NULL,因此如果prev->next已经有值,则会将其丢弃。这意味着您的链表只能是一个学生。如果您想将列表链接在一起,则应该

    newS->next = prev->next;
    prev->next = newS;
    
  • 你混淆了struct student **(这是readdb(&students)中传递的类型)和struct student * ......你需要找出你想要的东西,并坚持下去它。当前的addstudent代码只有在你有一个struct student实例(不是指针)的情况下才会起作用,然后将下一个初始化为NULL作为列表的头部。