C语言基础级——结构体

C语言基础级——结构体

转载请标明出处!


设计程序最重要的是选择一个表示数据的好方法。简单的变量、数组到复杂些的结构体、共同体和枚举,能够使数据表示形式更加地丰富、可观。

奶制品营养成分有能量(KJ)、蛋白质(g)、碳水化合物(g)等元素,市面上几种牛奶参数列表为:

奶制品 能量(KJ) 蛋白质(g) 碳水化合物(g)
豆本豆奶(SOY) 250 3.0 2.0
伊利(Yili) 277 3.2 4.8
蒙牛(Mon) 182 3.0 4.9

1. 结构体

完成结构体一系列动作三部曲:

  • 建立结构体的模板
  • 声明引入模板的变量
  • 对结构体各个成员进行访问

1.1 声明

奶制品营养成分有三种,采用结构体声明,如下:

struct milk
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
};
  • milk是一个可选的标记。

  • 该声明有个成员,一个是int类型,两个是float类型。

  • 结构体声明并没有创建出一个实际的数据对象,我们可以认为它是属于模板。这个模板是适用于豆本豆(SOY_MILK),伊利(Yili_MILK),蒙牛(Mon_MILK)的奶制品。

所以我们还需要做以模板为标准创建出三个结构体变量,这三个结构体变量分别可以存放不同的奶制品参数。看到接下来这条指令之后,编译器使用milk模板为 SOYMonYili 分配内存空间,如下:

// 可放在函数内部和外部, 且声明之后, 将会为其分配内存空间。
struct milk SOY;
struct milk Mon;
struct milk Yili;

如果只需要使用一个结构体变量,通常可选的标记为小写,而结构体类型名为首字母大写。以豆本豆为例,如下:

struct milk
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
} SOY;
// 还是适用
struct milk Mon;
struct milk Yili;

这样写的话,代码可读性明显降低。(注意:我们还可以把可选标记去掉,让此结构体只用于豆本豆),如下:

struct
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
} SOY;
// 不适用
struct milk Mon;
struct milk Yili;

// 再建立新的结构体, 这样才适用。
struct
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
} Mon;

1.2 初始化

数组其中的一种初始化:

int a[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

那么,结构体的初始化和数组的相似的,有三种方式:

  • 第一种
struct milk
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
};

struct milk SOY = {
    
    
    250,
    3.0,
    2.0
};
  • 第二种 C99标准还支持:
struct milk
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
};

// 部分初始化
struct milk SOY = {
    
    
    .energy = 250,
};

// 全部初始化
struct milk SOY = {
    
    
    .energy 		= 250,
    .protein 		= 3.0,
    .carbohydrate 	= 2.0
};
  • 第三种 重定义初始化:
typedef struct 
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
} milk;

milk SOY = {
    
    
    250,
    3.0,
    2.0
};

1.3 访问结构体成员

1.3.1 (.) 和 (->) 区别

1.3.1.1 (.) 成员运算符
  • 成员选择为对象(.),可读作“的”。
  • 13行,是结构体变量(SOY)“的” 能量(energy) 等于 250,如下:
#include<stdio.h>

struct milk
{
    
    
    int energy;
    float protein;
} ;

// 声明结构体变量
struct milk SOY;

int main()
{
    
    
    // 通过结构体变量进行访问
    SOY.energy = 250;
    SOY.protein = 2.0;
    
    printf("%d\n", SOY.energy);
    printf("%f\n", SOY.protein);
    return 0;
}

1.3.1.2 (->) 间接运算符
  • 成员选择为指针(->),表示为指向结构体的指针。
  • 19行,通过指针变量(SOYPtr)访问结构体变量(SOY)的能量(energy)成员的地址。
  • 与普通的变量指针用法相似。如下:
#include<stdio.h>

struct milk
{
    
    
    int energy;
    float protein;
} ;

// 声明结构体变量
struct milk SOY;
// 声明结构体指针变量
struct milk *pSOY;

int main()
{
    
    
    // 这一步不能省略,否则将会出现段错误。
    pSOY = &SOY;
    
    // 通过指针变量进行访问
    pSOY->energy 	= 250;
    pSOY->protein 	= 2.0;
    
    printf("%d\n", pSOY->energy);
    printf("%f\n", pSOY->protein);
    return 0;
}

1.4 typedef

typedef是一种高级数据特性,可以给某一个类型创建新的名字,为了能够为经常出现的类型创建一个方便的、可识别的名称,如下:

// 声明结构体
typedef struct
{
    
    
    int     energy;
    float   protein;
    float   carbohydrate;
} Milk;
// 声明结构体变量
Milk SOY;
Milk Mon;
Milk Yili;

浅谈,我们在单片机程序应用当中,常常会使用typedef给某些类型重新命名来使用(今后会出一个专题讲解宏定义与重命名区别),如下:

typedef unsigned char BYTE;
typedef char* STRING;
#include<stdio.h>

// 重命名uchar类型与char*
typedef unsigned char BYTE;
typedef char* STRING;

int main()
{
    
    
    BYTE    param   = 'H';
    STRING  str     = "Home";
    
    printf("%c\n", param);
    printf("%s\n", str);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43125185/article/details/110389043