【C语言】结构类型的定义和使用

目录

1.结构体(struct)类型

2.结构标记

3.typedef

4.定义结构数组的方法

5.调用结构数组的方法

6.将结构体传入函数

7.结构体使用实例


1.结构体(struct)类型

在C语言中,结构体(struct)类型是一种用户自定义的复合数据类型,用于组合不同类型的数据成员在一个单独的对象中。结构体类型的定义可以包含多个数据成员,每个数据成员可以是不同的数据类型。结构体类型的语法如下:

struct 结构体名 {
    数据类型 成员名1;
    数据类型 成员名2;
    // ...
};

以下是一个示例:

struct student {
    int id;
    char name[20];
    int age;
    float score;
};

上述代码定义了一个名为student的结构体类型,包含了四个数据成员:idnameagescore,分别为整型、字符数组型、整型和浮点型。该结构体类型可以用于定义表示学生的对象,每个对象包括了学生的ID、姓名、年龄和分数。结构体类型创建后,需要通过声明一个结构体变量来实际分配内存,例如:

struct student s; // 声明一个名为s的结构体变量,表示一个学生
s.id = 1001; // 设置学生的ID为1001
strncpy(s.name, "Tom", sizeof(s.name)); // 设置学生的姓名为Tom
s.age = 20; // 设置学生的年纪为20
s.score = 90.5; // 设置学生的分数为90.5

2.结构标记

C语言中,结构标记指的是定义一个结构体类型的名称,而不是直接定义结构体变量。结构标记的声明格式如下:

c 复制代码
struct 结构体名称;

例如,以下是一个结构标记的声明:

c 复制代码
struct student;

这个声明定义了一个名为"student"的结构体类型,但没有定义具体的结构体成员。这是因为结构标记只是为结构体类型分配了一个名称,而没有为它分配内存空间。

结构标记的主要作用是方便在后面的代码中使用结构体类型。可以使用结构标记名称来声明结构体变量、作为函数参数类型以及作为函数返回类型等。

3.typedef

C语言中,typedef是一种定义类型别名的关键字。它的用法如下:

  • 声明简单类型别名

    typedef 原类型别名 新类型别名;

例如:

typedef int INT;
INT a = 1;

这样将int类型的a定义为INT类型的变量。

  • 声明结构体类型别名

    typedef struct 原类型别名 新类型别名;

例如:

typedef struct date {
    int year;
    int month;
    int day;
} DATE;
DATE d = {2021, 10, 1};

这样将struct date类型的d定义为DATE类型的变量。

  • 声明指针类型别名

    typedef 原类型别名 * 新类型别名;

例如:

typedef int * PTR_INT;
int i = 1;
PTR_INT ptr_i;
ptr_i = &i;

这样将int类型的指针定义为PTR_INT类型的指针变量。

使用typedef可以使代码更加简洁易懂,提高代码的可读性。

4.定义结构数组的方法

定义结构数组的方法如下:

struct student {
    char name[20];
    int age;
    char gender;
};

struct student stu[3]; // 定义一个包含3个元素的结构数组

这里定义了一个结构体 student,包含了学生的姓名、年龄和性别,然后通过结构体定义一个包含3个元素的结构数组 stu

5.调用结构数组的方法

调用结构数组的方法如下:

#include <stdio.h>

int main() {
    struct student stu[3] = {
        {"Tom", 18, 'M'},
        {"Lucy", 19, 'F'},
        {"John", 20, 'M'}
    };

    for(int i = 0; i < 3; i++) {
        printf("Name: %s\n", stu[i].name);
        printf("Age: %d\n", stu[i].age);
        printf("Gender: %c\n", stu[i].gender);
    }
    return 0;
}

这里通过初始化方式给结构数组赋值,然后使用 for 循环输出每个学生的信息。在输出时使用了结构体成员连接运算符 .(点号) 来访问每个学生的姓名、年龄和性别。

C语言中的结构体是一种自定义的数据类型,可以包含多个不同类型的数据成员。结构体的定义可以在函数内部或外部,格式为:

struct 结构体名 {
    数据类型 成员名1;
    数据类型 成员名2;
    ...
};

其中,结构体名是自己定义的,可以起任何名字。成员名也可以任意取名,但要符合C语言的命名规则。

结构体变量定义格式为:

struct 结构体名 变量名;

访问结构体成员时使用"."操作符,格式为:

变量名.成员名

例如:

struct student {
    char name[20];
    int age;
    float score;
};

int main() {
    struct student s1;
    strcpy(s1.name, "Tom");
    s1.age = 18;
    s1.score = 88.5;
    printf("%s's age is %d, score is %.1f\n", s1.name, s1.age, s1.score);
    return 0;
}

输出结果为:

Tom's age is 18, score is 88.5

6.将结构体传入函数

结构体可以像其他数据类型一样传递给函数。下面是一些示例代码:

假设有以下结构体:

c 复制代码
typedef struct Person {
    char name[30];
    int age;
} Person;
  • 将结构体作为函数参数

将结构体作为函数的参数,可以通过值传递或指针传递。

c 复制代码
void print_person(Person p) {
    printf("姓名:%s,年龄:%d\n", p.name, p.age);
}

void update_person(Person *p) {
    p->age += 1;
}

在这个示例代码中,我们定义了两个函数。print_person函数用于打印结构体Person中的信息,update_person函数用于修改结构体Person中的信息。print_person函数使用的是值传递,即将结构体Person的值作为参数传递给函数。update_person函数使用的是指针传递,即将结构体Person的指针作为参数传递给函数。

  • 将结构体指针作为函数参数

如果要在函数中修改结构体的值,可以将结构体的指针作为参数传递给函数。这样可以避免在函数内部创建新的结构体副本。

c 复制代码
void update_person(Person *p) {
    p->age += 1;
}

在此示例代码中,我们定义了一个update_person函数,它使用了指针传递。函数使用->运算符来访问结构体中的成员。

调用上述函数的方法如下:

c 复制代码
Person person = {"Tom", 20};
print_person(person); // 输出 "姓名:Tom,年龄:20"
update_person(&person);
print_person(person); // 输出 "姓名:Tom,年龄:21"

7.结构体使用实例

利用结构体求投票数

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CANDIDATES 10

// 候选人结构体
typedef struct Candidate {
    char name[50]; // 候选人名字
    int vote_count; // 票数
} Candidate;

int main() {
    int num_candidates;
    Candidate candidates[MAX_CANDIDATES];

    // 获取候选人数量
    printf("请输入候选人数量(最多%d个):", MAX_CANDIDATES);
    scanf("%d", &num_candidates);
    getchar(); // 消耗输入缓冲区中的换行符

    // 获取候选人信息
    for (int i = 0; i < num_candidates; i++) {
        printf("请输入候选人%d的名字:", i+1);
        fgets(candidates[i].name, 50, stdin);
        candidates[i].name[strcspn(candidates[i].name, "\n")] = '\0'; // 去除输入缓冲区中的换行符
        candidates[i].vote_count = 0; // 初始化票数为0
    }

    // 投票
    while (1) {
        char candidate_name[50];
        printf("请输入你要投票的候选人名字(输入exit结束投票):");
        fgets(candidate_name, 50, stdin);
        candidate_name[strcspn(candidate_name, "\n")] = '\0';

        if (strcmp(candidate_name, "exit") == 0) {
            break;
        }

        int found = 0;
        for (int i = 0; i < num_candidates; i++) {
            if (strcmp(candidate_name, candidates[i].name) == 0) {
                candidates[i].vote_count++;
                found = 1;
                break;
            }
        }

        if (!found) {
            printf("没有找到名为%s的候选人,请重新输入。\n", candidate_name);
        }
    }

    // 输出投票结果
    printf("投票结果:\n");
    for (int i = 0; i < num_candidates; i++) {
        printf("%s: %d 票\n", candidates[i].name, candidates[i].vote_count);
    }

    return 0;
}

在这个例子中,我们定义了一个候选人结构体,包含了候选人的名字和票数。在程序运行时,首先获取候选人数量和候选人信息,并初始化各个候选人的票数为0。然后,利用一个循环获取用户输入的投票信息,直到用户输入exit为止。每次获取到用户输入的候选人名字后,我们遍历候选人数组,查找是否有对应的候选人。如果找到了,则给该候选人的票数加1;否则输出错误提示信息。最后,我们输出投票结果,显示每个候选人的名字和票数。

相关推荐
QAQ小菜鸟5 分钟前
一、初识C语言(1)
c语言
何曾参静谧20 分钟前
「C/C++」C/C++ 之 变量作用域详解
c语言·开发语言·c++
互联网打工人no124 分钟前
每日一题——第一百二十一题
c语言
朱一头zcy2 小时前
C语言复习第9章 字符串/字符/内存函数
c语言
此生只爱蛋2 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
何曾参静谧2 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
lulu_gh_yu3 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>5 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
EricWang13587 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??7 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++