C语言学习之结构体

结构体类型的定义

结构体类型由不同的数据类型的数据组成,这些数据称为该结构体类型的成员项。在程序中使用结构体时,必须先定义结构体类型。

结构体定义的格式:

struct 结构体类型名{

      数据类型 成员名1;

      数据类型 成员名2;

   ………………

};

说明:
(1)struct是定义“结构体类型”的关键字,其后的“结构体类型名”由程序员命名:
(2)其中各成员项的数据类型可以是基本数据类型,也可以是数组、指针等类型。还可以是其他结构体类型,即实现结构体类型的“嵌套定义”。
例如,定义一个表示学生的结构体类型,结构体类型名为student,有四个成员项:学号、姓名、年龄和性别,如下所示:

struct student{

          int number;  //学号,整型
        char name[10]; //姓名, 字符数组型

         int  age;  //年龄,整型
         char sex[2] ;  //性别,字符数组型 
};
再例如,对上例定义的类型中增加一个成员项datel(“出生日期”),该成员项是由另一结构体类型 DATE定义的变量。为实现这一要求,必须先定 义结构体类型 “DATE”,再定义结构体类型"student”,两者的定义顺序不能颠倒。如下所示:
/*先定义结构体类型"struct DATE" */

struct  DATE {
        int year;   // 年

     int month;  //月

      int day;      //日

};
struct  student{
           int number;

          char name[10];

          int age;
          char sex[2];

   struct DATE date;   //出生日期,DATE 类型,利用“嵌套定义”

};

    结构体类型允许“嵌套定义”,但不允许出现“递归定义”,因为这样无法确定结构体类型所占内存空间的大小。例如,以下定义是不合法的
struct DATE{
            int year;

            int month;

            int day;
            struct DATE date;     //不合法 ! 不允许“递归定义”

]
    如果结构体类型中有些成员项是同一数据类型,也可以像定义变量时一起定义,之间用逗号分隔。例如,以下形式也是合法的。
struct DATE{
      int year , month, day;

    };
struct student{
               int number, age;
               char name[10],sex[2];

              struct DATE date;

};
     另外,结构体类型中的成员项可以和程序中的其他变量名相同:不同结构体类型中的成员项也可以同名。
     不同数据类型在系统中所占内存空间是不同的,结构体类型所占内存空间的大小是其所包含的各个成员项所占内存大小之和。需要注意的是,像其他数据类型一样,系统是不会给数据类型分配内存空间的,只有用类型定义了变量之后才才分配相应的内存空间。

结构体变量的定义
    变量必须先定义再引用,结构体变量也是如此。结构体变量定义的格式有以下三种:

1.先定义结构体类型,再定义结构体变量

例如:
struct student{
       int number;   //学号
      char name[10]; //姓名  ET共用体和权举 型3int age; //年龄

      char sex[2]; //性别

   };

struct student stu1,stu2;  //定义结构体变量stu1和stu2,为student结构类型

struct student相当于定义类型(结构体类型) ,stu1相对于定义变量

  说明:此种形式最为常用,结构体类型的定义可以放在所有函数之外,结构体变量的

2.定义结构体类型的同时,定义结构体变量

例如:

      struct student{

               int number;  //学号

               char name[10]; //姓名

                 int age;  / /年龄

                char sex[2];  //性别

}stul, stu2;

      说明:结构体类型的定义一般放在所有函数之外,那么上例中的结构体变量stul和stu2就会成为“全局变量“。相比较不如第(1)种方式灵活。

   3. 定义结构类型的同时定义结构体变量,并且省略结构体类型名

      例如:

      struct (

                int number;       //学号

              char name[10];  //姓名

              int age;  / /年龄

             char sex[2] ;  //性别

}stu1, stu2;

      说明:省略了结构体类型名,每次定义变量时都必须重新书写结构体成员项,较为繁琐,因此该方式虽然合法,但不常用。

结构体变量的引用与初始化

 1.结构体变量的引用

  1)对结构体变量成员项的引用

      变量定义之后就可以引用,结构体变量可以包含多个成员项,引用其成员项的方式如下:

      结构变量名.成员名

      其中,”.”是结构体成员运算符,它在所有运算符中优先级别最高。

例8.1引用结构体变量成员项示例。

#include <stdio.h>
struct DATE
{
	int year,month,day;};
struct student
{
	int number;
	char name[10];
	int age;
	char sex[2];
	struct DATE date;
};
void main()
{
     struct student stu;
     printf("input number:");
	 scanf("%d",&stu.number);
	 printf("input name:");
	 scanf("%s",&stu.name);
	 printf("input age:");
	 scanf("%d",&stu.age);
	 printf("input sex:");
	 scanf("%s",&stu.sex);
	 printf("input date:");
	 scanf("%d-%d-%d",&stu.date.year,&stu.date.month,&stu.date.day);
	 printf("学号:%d,姓名:%s,年龄:%d,性别:%s,\n出生日期:%d-%d-%d",stu.number,stu.name,stu.age,stu.sex,stu.date.year,stu.date.month,stu.date.day);
}


注意:遇到嵌套定义的成员项时,按照嵌套的顺序层层引用,如题中成员项“出生日期的年”

2)对结构体变量的整体引用

相同类型的结构体变量之间可以整体赋值,系统会自动将各成员项的值进行对应赋值操作

例如:

struct student stu1,stu2;

stu1=stu2;

对于结构体变量中的内嵌结构体变量也可以整体赋值。例如stu1.date=stu2.date

2. 结构体变量的初始化
      所谓“结构体变量初始化”,就是在定义结构体变量的同时可以对其各成员项按照定义顺序逐一进行赋值, 并且各成员项的初值要与定义的数据类型一致。
      由于定义结构体变量的方式有三种,因此初始化的方式也有三种。

例如:第1种:

      struct student{

                  int number;  //学号

                char name[10]; //姓名

                   int age;  //年龄

                 char sex[2];  //性别

};

      struct student stu1={120101,"liming",20, "男"};

第2种:

      struct student{

                    int number;  //学号

                   char name[10]; //姓名

                      int  age;  //年龄

                     char sex[2] ;  //性别

      }struct student stul= (120101, "liming",20, "男"};

第3种:

      struct   {

                   int number;  //学号

                  char name[10]; //姓名

                   int age;    // 年龄

                  char sex[2];  //性别

      }struct student stul=(120101, "1iming",20,"男"};

   对于嵌套定义的结构体变量在初始化时,逐层细化,一直 到最基本的数据类型变量,例如:

      struct DATE (

                int year, month, day;

};

      struct student{

                int number;

              char name [10];

                 int age;

                char sex[2];

           struct DATE date;

};
      struct student stu= (120101, "11ming",20,“男",1993,5,8};

结构体数组

1.结构体数组的定义

      由同一结构体类型变量组成的数组称为结构体数组,即数组中的元素都是同一结构体类型的变量。与其他类型数组一样,其定义的格式如下:

      struct  结构体类型名  结构体数组名[元素个数];

   相仿定义结构体变量,结构体数组的定义也有三种方式。

1)先定义结构体类型,再定义结构体数组

例如:

      struct student(

                 long int number;  //学号

                 Char name[10];  //姓名

                   float score[2];  //两门课程成绩

};

 struct student stu[5]; //定义结构体数组

2)定义结构体类型的同时,定义结构体数组

例如:

      struct student {

                long int number;  //学号

               char name[10];  //姓名

                 float score[2];  //两门课程成绩

         }stu[5];     //定义结构体数组

3)l利用无结构体类型名定义结构体数组

例如:

      struct {

               long int number; //学号

               char name[10];  //姓名

                float score[2];  //两门课程成绩

        } stu[5];        //定义结构体数组

2.结构体数组的引用与初始化

1)结构体数组的引用

 例:定义一个存放3名学生的结构体数组,每名学生的信息包括学号、姓名、两门课程成绩。录入3名学生的信息,并显示输出。

#include <stdio.h>
struct student
{
   long	int number;
	char name[10];
	float score[2];    //两门课成绩
};
void main()
{
     struct student stu[3];  //定义结构体数组stu
	 int i,j;
	 for(i=0;i<3;i++)
	{
       printf("input number:");
	   scanf("%ld",&stu[i].number);
	   printf("input name:");
	   scanf("%s",&stu[i].name);     //数组名name表示地址
	   printf("两门课成绩:");
	   for(j=0;j<2;j++)
		   scanf("%f",&stu[i].score[j]);
	}
	 printf("学号    姓名    C语言   英语\n");
	 for(i=0;i<3;i++)
	{
	    printf(" %ld  ",stu[i].number);
		printf(" %s  ",stu[i].name);
	    for(j=0;j<2;j++)
		    printf("%4f",stu[i].score[j]);
	    printf("\n");
	}
}

2)结构体数组初始化

   与其他类型的数组一样,结构体数组也可以进行初始化。
struct  student{

          long int number;   //学号

        char  name[10];     //姓名
          float score[2];        //两门课程成绩     

};

struct student stu[3]={{1911,"const",{33,44}}, {1912,"const2",{99,44}},{1911,"const3",{88,55}}};

结构体指针
    指向结构体类型变量的指针称为“结构体指针”,与前面讲述的指针概念类似,结构体指针在使用之前,也必须有明箱的指向。其定义格式为:
           struct   结构体类型名  *结构体指针名;

例如:
        struct student {
                   long int number;          //学号

                   char name[10];           //姓名

                    float score[2];             //两门课程成绩

};
struct student stu, *p;       //定义结构体变量stu和结构体指针P
       定义stu是类型为struct student的结构体变量,p是指向该类型对象的指针变量。需要注意的是:经过上面的定义,此时p尚未指向任何具体的对象。利用以下的赋值语句,明确了指针p指向结构体变量stu的地址。

p=&stu;
1.结构体指针与结构体变量
     结构体指针给我们提供了两种新的引用结构体成员项的方法,即:

  *(结构指针变量名),成员名
  结构指针变量名->成员名
说明:第一种形式中的圆括号不能省略,第二种形式中员运算符“.”同处于最高级,结合方向是从左至右
例:利用结构体指针引用结构体变量成员项示例

#include <stdio.h>
struct DATE
{
	int year,month,day;};
struct student
{
	int number;
	char name[10];
	int age;
	char sex[2];
	struct DATE date;
};
void main()
{
     struct student stu,*p;
	 p=&stu;
     printf("input number:");
	 scanf("%d",&(*p).number);
	 printf("input name:");
	 scanf("%s",&(*p).name);
	 printf("input age:");
	 scanf("%d",&(*p).age);
	 printf("input sex:");
	 scanf("%s",&(*p).sex);
	 printf("input date:");
	 scanf("%d-%d-%d",&(*p).date.year,&(*p).date.month,&(*p).date.day);
	 printf("学号:%d,姓名:%s,年龄:%d,性别:%s,\n出生日期:%d-%d-%d",p->number,p->name,p->age,p->sex,p->date.year,p->date.month,p->date.day);
}

注意:指针在使用前一定要明确指向,如题中p=&stu;

typedef类型声明

关键字typedef的作用是为一个已经定义的数据类型取一个别名。其格式为:

typedef 类型名1 类型名2;

类型名1为系统提供的标准类型名(如int float char),或是已经定义过的其他类型名(如结构体类型);类型名2位程序员为类型1自定义的别名。

其目的是为了简化程序中的类型名。

typedef int ABC;  //给int类型取别名ABC

定义变量:

ABC n;等价于int  n;

再例如:

typedef struct student{

     char name[10];

     int age;

}stu;

以上定义,相当于给类型名“struct student”取了别名stu。因此,在程序中可以用stu来替代struct sutdent进行变量定义。

stu stu1,stu2,*p;

等价于

struct student stu1,stu2,*p;

题目:

有以下定义:

struct student{char name[9];int age;};

struct student stu[10]={"Ann",17,"John",19,"Mary",18,"Linda",16,};

能输出M的语句是:printf("%c\n",stu[2].name[0]);

若要说明一个类型名STP,使得定义语句STP s;等价于int *s;

typedef int* STP

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页