C程序设计谭浩强版总结笔记

结构体

注:结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如struct Student)。结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。上面的结构体声明中Student就是结构体名(结构体标记)

说明
struct 结构体名
{成员列表}
类型名 成员名;
“成员列表”也称为“域表”

struct Student
{
    int num;
    char name[20];
    char sex;
    int age;
    float score;
}

注:

  1. 如果成员本身又属于一个结构体类型,则要用若干成员运算符,一级一级找到最低级的成员。只能对最低级的成员进行赋值或存取以及运算。
  2. 同类的结构体变量可以相互赋值
    student1 = student2
  3. 可以引用结构体变量成员的地址,也可以引用结构体变量的地址
scanf("%d",&student1.num);
printf("%o",&student1);

声明和定义结构体类型变量

1. 声明和定义分开

声明结构体类型
sturct Student student1,student2;
定义结构体

student1.num = 10001;
student1.name = "zhangxin"; //此处如此赋值是不正确的,请自行百度如何正确赋值char数组。
student1.sex = "M"; 
student1.age = 19; 
student1.score = 90.5; 

student2.num = 10002;
student2.name = "wangli"; //此处如此赋值是不正确的,请自行百度如何正确赋值char数组。
student2.sex = "F"; 
student2.age = 20; 
student2.score = 98; 

2. 声明和定义同时进行

struct Student
{
    int num;
    char name[20];
    char sex;
    int age;
    float score;
}student1,student2;

注:该定义方法的一般形式为

struct 结构体名
{成员列表
}变量名列表;

3. 不指定类型名而直接定义

struct
{成员表列
}变量名表列;

说明:

  • 只能对结构体变量赋值而不能对结构体类型赋值。在编译时,结构体类是不分配空间的,只对变量分配空间。
  • 结构体类型中的成员可以与程序中的变量名相同,但二者不代表同一对象。例如,程序中可以另定义一个变量num,它与struct Student中的num是两回事,相互不干扰。

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

【例9.1】把一个学生的信息(包括学号、姓名、性别)放到同一个结构体变量中,并输出这个学生的信息

#include<stdio.h>
int main()
{
    struct Student
    {
        int num;
        char name[20];
        char sex;
        int age;
        // float score;
    }a={10101,"Li Lin",'M'};
    printf("学号:%d,姓名:%d,性别:%d。\n",a.num,a.name,a.sex,a.age);
    return 0;
}

定义结构体数组

  1. sturct 结构体名
    {成员列表} 数组名【数组长度】;
    struct Person
    {
        char name[20];
        int count;
    }leader[3];
    
  2. 结构体类型 数组名【数组长度】;
    struct Person leader[3];
    

定义结构体数组
【例9.3】有三个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先输入被选人的名字,最后输出各人得票结果。

#include<string.h>
#include<stdio.h>
struct Person()
{
    char name[30];
    int count;
}leader[3]={"Li",0,"zhang",0,"sun",0};

int main()
{
    int i,j;
    char leader_name[20];
    for(i=1;i<=10;i++)
    {
        scanf("%s",leader_name);
        for(j=0;j<3;j++)
        {
            if(strcmp(leader_name,leader[j].name==0))
                leader[j].count++;
        }
    }
    printf("\nResult:\n");
    for(i=0;i<3;i++)
        printf("%5s:%d\n",leader[i].name,leader[i].count);
    return 0;
}

指向结构体变量的指针

struct Student *pt

【例9.5】通过指向结构体变量的指针变量输出结构体变量中的成员信息

#include<stdio.h>
#include<string.h>
int main()
{
    struct Student
    {
        long num;
        char name[20];
        char sex;
        float score;
    };
    struct Student stu_1;
    
    return 0;
}

注:以下三种等价

  1. stu成员名(如stu.num)
  2. (*p).成员名(如( *p).num)
  3. p->成员名(如p->num)

指向结构体的指针

【例9.6】有3个学生的信息,放在结构体数组中,要求输出全部学生的信息

#include<stdio.h>
struct Student
{
    int num;
    char name[20];
    char sex;
    int age;
};
struct Student stu[3]={{10101,"Li",'M',18},
{10102,"zhangfang",'M',19},{10104,"wangmin",'F',20}};
int main()
{
    struct Student *p;
    printf("No.     Name        sex age\n");
    for(p=stu;p<stu+3;p++>)
    {
        printf("%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);
    }
    return 0;
}

注:

  1. 如果p的初值为stu,即指向stu的序号为0的元素,p加1后,p就指向下一个元素。例如:
    (++p)->num //先使p自加1,然后得到p指向的元素中num成员值(即10102)
    (p++)->num//先求得p->num的值(即10101),然后再使得p自加1,指向stu[]
  2. p指针用来指向一个struct Student类型对象,不应用指向stu数组元素中的某一成员。
    p = stu[1].name;//不合法,stu[1].name是stu[1]元素中成员name首字符的地址。编译时将会给出“警告”信息,表示地址的类型不匹配。
    
  3. 如果将某一个成员地址赋值给p,例如p = (struct Student*) stu[0].name; 此时,p的值是stu[0].name成员的起始地址。但是p仍然保留原来的类型。如果执行printf("%s",p+1);,则会输出stu[1]中name的值。执行p++时,p的值的增量是结构体struct Student的长度。

用结构体变量和结构体变量的指针做函数参数

struct Student
{
    int num;
    char name[20];
    float score[3];
    float aver;
}

1. 结构体变量做函数参数

void input(struct Student stu);

2. 结构体变量的指针/数组做函数参数

void input(struct Student stu[]);

指针处理链表

注:C程序设计 谭浩强版此处有9.4节“用指针处理链表”本人将其归类到了第八章指针中

共用体

格式:
union 共用体名
{成员表列}变量表列;
例如

union Data
{
    int i;
    char ch;
    float f;
}a,b,c;

注:结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长成员的长度。

引用共用体变量

a.i
a.ch
a.f

特点

  1. 同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。
    union Date
    {
        int i;
        char ch;
        float f;
    }a;
    a.i = 97;
    printf("%d",a.i);   //输出97
    printf("%c",a.ch);  //输出a
    printf("%f",a.f);   //输出实数0.00000
    
    注:整型无法用浮点型的格式输出,故printf("%f",a.f);输出为0
  2. 对共用体量化,但是初始化表只能有一个常量
    union Date
     {
         int i;
         char ch;
         float f;
     }a = {1,‘a’,1.5};   //此处错误
    
  3. 共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有的变量存储单元中的值就被取代了。
  4. 共用体变量的地址和它的成员的地址是相同的。
  5. 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。
    a = 1;
    m = a;
    
  6. C99之前不允许共用体变量作为函数参数,只能通过指针的形式做函数参数,C99之后允许了。
    注:共用体类型一般用在两个组数据的成员大部分相同的情况之下。例如,有学生和老师两组数据,学生的成员包括:姓名、号码、性别、职业、班级。教师的成员包括:姓名、号码、性别、职业、职务。这两组数据只有班级和职务不同,因此可以定义成如下的共用体:
struct
{
    char name[20];
    char sex;
    char job;
    union
    {
        int class;
        char position[10];
    }category;
}person[2];

枚举类型

注:枚举类型放在了第3章“顺序程序设计”

typedef声明新类型名

注:typedef声明新类型名放在了第3章“顺序程序设计”

上一篇:按等级统计学生成绩PTA


下一篇:JAVA中的反射