c语言的结构体

1.结构体的概念
结构体是一种复合型数据类型,同属于复合型数据类型的还有联合体。结构体可以理解为是一种自定义类型,用于对其他数据类型(什么int型,double型,float型等等)的打包。c语言中正是因为结构体的存在,使其代码具有封装性,可以基于面向对象思想来编程。

2.结构体的声明、定义
假设我们要用结构体来表现一个班级的信息,可以为:
struct class_t{
    char* className;    //班别
    int stuCnt;         //班级学生个数
    char **stuName;     //班级中每个同学的姓名
};

这样去声明结构体(上面的声明操作并不会占据内存空间),在定义 
结构体变量的时候需要指定关键字“struct”:

struct class_t class;

另外提一句,c++也有结构体,c++定义结构体变量的时候就不需要“struct”关键字。 
在实际运用中,我们会采用typedef声明的方式:

typedef struct _class_t{
    char* className;    //班别
    int stuCnt;     //班级学生个数
    char **stuName; //班级中每个同学的姓名
}class_t;

//或者

typedef struct{
    char* className;    //班别
    int stuCnt;     //班级学生个数
    char **stuName; //班级中每个同学的姓名
}class_t;

这样子的声明方式,就可以直接去掉“struct”关键字来定义结构体对象:

class_t class;

除此之外,还有如下几种常见的声明方式:

// 1. 前向声明
struct class_t class;
structclass_t {
    char* className;
    int stuCnt;     
    char **stuName;
};

//2. 前向typedef
typedef struct class_t CLASS_T;
structclass_t {
    char* className;
    int stuCnt;     
    char **stuName;
};

//3. 声明立即定义
structclass_t {
    char* className;
    int stuCnt;     
    char **stuName;
}class; 

//适用于只需要生成一次结构体变量的场合
struct {
    char* className;
    int stuCnt;     
    char **stuName;
}class;

3.结构体变量的赋值
对结构体变量内的成员的操作可分为初始化(定义的时候赋值)和赋值2种场合: 
(1)初始化

typedef struct _class_t{
    char* className;
    int stuCnt;     
    char **stuName;
}class_t;

int main(void)
{
    class_t class1 = {"13电子2班", 25, NULL};
    return 0;
}

还有另外一种初始化方法,可以针对指定变量来初始化:

int main(void)
{
    class_t class = {
        .className = "13电子2班",
        .stuCnt = 26,
    };
    return 0;
}

这种初始化方法在LINUX系统底层开发见到的极其多。这两种初始化方法都属于批量赋值,注意它们只能在定义结构体变量的时候使用。 
(2)赋值操作


int main(void)
{
    class_t class1;

    //赋值操作
    class1.className = "13电子2班";
    class1.stuCnt = 25;
    class1.stuName = NULL;

    return 0;
}

4.结构体在函数间的传递

结构体变量在函数间传递的时候是具有普通变量的特性,即拷贝原则。

void testFunc(class_t class)
{
    printf("testFunc: class = %p\n", &class);   
}

int main(void)
{
    class_t class1;
    int num = 10;

    ...
    printf("main: class1 = %p\n", &class1); 
    testFunc(class1);

    return 0;
}

运行结果: 

è¿éåå¾çæè¿°
 
二者的地址值不同,再次说明,主调函数并非传递结构体的地址给被调函数。地址不相同,那么在被调函数中修改结构体成员的值自然也不会修改到main中函数中的结构体。想要让形参的修改后能修改到实参,就需要使用结构体指针了。 
结构体变量在函数中的传递既然是值拷贝,也就是说可以像普通变量之间的赋值咯,像a = b那样,确实如此:

int main(void)
{
    class_t class1, class2;

    class1.className = "13电子2班";
    class1.stuCnt = 25;
    class1.stuName = NULL;

    //结构体变量可以像普通变量间的赋值操作一样
    class2 = class1;
    printf("class2.stuCnt = %d\n", class2.stuCnt);
    return 0;
}

运行结果: 

è¿éåå¾çæè¿°
 
注意,前面讲到,对结构体变量的批量赋值操作只能在定义结构体变量的时候使用,即下面操作语法错误:

class_t class2;

class3 = {"16届电子2班", 25, NULL};        //报错error: expected expression before ‘{’ token
根据变量之间的赋值特性,对赋值部分进行强制类型转换使其成为一个没有变量名的变量,那么批量赋值操作就通过语法了:

class3 = (class_t){"13计算机应用2班", 30, NULL};  
class4 = (class_t){

                   .className = "16届电子2班", 
                   .stuCnt = 25,
                   .stuName = NULL};        
--------------------- 
原文:https://blog.csdn.net/qq_29344757/article/details/62041838 
 

猜你喜欢

转载自blog.csdn.net/u012308586/article/details/90203692