C语言基础03:结构体&结构体与指针

一、什么是结构体
结构体是一种构造数据类型。把不同的数据类型整合起来成为一个自定义的数据类型。关键字 struct。代码示例如下:

struct Man{
    //成员
    int age;
    int height;
    char name[20];
};

初始化结构体实例的方式:
方式一:

struct Man man = { 12, 70, "jack" };

方式二:

struct Man man;
man.age = 12;
man.height = 70;
strcpy(man.name,"jason");

二、结构体的几种写法
1.用一条语句声明结构和该结构的实例

struct Man{
    int age;
    int height;
    char name[20];
} m1, m2 = {12,70,"刘德华"};

m1 和 m2 都是结构体Man的变量,并且对m2进行了初始化。

2.匿名结构体的写法

struct {
    int age;
    int height;
    char name[20];
} man;

用一条语句声明结构和该结构的实例时,可以省略标记符的名字。使用这种方式的最大缺点是不能在其他语句中定义这个结构的其他实例。这个结构类型的所有变量必须在一行语句中定义。

三、结构体的嵌套
可以将第一个结构用作第二个结构的成员,再将第二个结构用作第三个结构的成员,依次类推。

struct Teacher{
    int age;
    int height;
    char name[20];
};
struct Student{
    int age;
    int height;
    char name[20];
    struct Teacher teacher;
};

C编译器只允许结构最多15层,如果结构有这么多层,则引用最底层的成员时,需要输入所有的结构成员名称。赋值方式如下:

//赋值方式一
struct Student s1 = { 12, 70, "jack", { 23, 70, "Boss wang" } };
//赋值方式二
struct Student s2;
s2.age = 12;
s2.height = 70;
strcpy(s2.name,"jack");
strcpy(s2.teacher.name,"Boss wang");

结构体嵌套还有一种写法:声明结构中的结构

struct Student{
    int age;
    int height;
    char name[20];
    struct Teacher{
        int age;
        int height;
        char name[20];
    } teacher;
};

这个声明将Teacher结构声明放在Student结构的定义内,因此不能在Student结构的外部声明Teacher变量。使用下面的语句会导致编译错误:

struct Teacher my_teacher;

四、结构指针
要获得结构的地址,就需要使用结构的指针。

struct Man{
    int age;
    int height;
    char name[20];
};
struct Man man = { 12,70,"jack" };
struct Man *p = &man ;
printf("%d,%s\n", (*p).age, (*p).name);
printf("%d,%s\n", p->age, p->name);

(*p).agep->age 的写法是等价的。通常使用第二种方法。

五、结构数组

struct Man{
    int age;
    int height;
    char name[20];
};
struct Man mans[ ] = { {12,70,"jack"},{13,60,"jason"} };
struct Man *p = &mans ;
//遍历结构体数组
for (; p < mans + 2; p++){
    printf("%s,%d\n",p->name,p->age);
}

六、结构体的大小

struct Man{
    int age;
    int height;
    char name[20];
};
struct Man man = { 12, 90,"jack" };
printf("%#x,%d", &man, sizeof(man));
C语言基础03:结构体&结构体与指针_第1张图片
结构体大小

结构体变量的大小,必须是最宽基本数据类型的整数倍。

七、为结构体动态分配内存

struct Man{
    int age;
    char *name;
};

//结构体与动态内存分配
void main(){
    struct Man *m_p = (struct Man*)malloc(sizeof(struct Man) * 10);
    struct Man *p = m_p;
    p->name = "jack";
    p->age = 12;
    p++;
    p->name = "baby";
    p->age = 16;
    struct Man *loop_p = m_p;
    for (; loop_p < m_p + 2; loop_p++){
        printf("%s,%d\n", loop_p->name, loop_p->age);
    }
    free(m_p);
    m_p = NULL;
    getchar();
}

注:malloc()函数返回的值是一个void指针,因此必须用表达式 (struct Man*)将它转换成所需要的类型。

八、类型取别名
关键字:typedef

typedef struct Man{
    int age;
    char *name;
}JavaMan, *JM;

void main(){
    //结构体变量
    JavaMan javaMan = { 12 ,"jack"};
    //结构体指针
    JM jm = &javaMan;
    printf("%d,%s\n",javaMan.age,javaMan.name);
    printf("%d,%s\n", jm->age, jm->name);
    getchar();
}

九、结构体函数指针成员

typedef struct Girl{
    char *name;
    int age;
    //函数指针
    void(*sayHi)(char *content);
}Girl, *GirlP;

void sayHi(char *content){
    MessageBox(0, content, "标题", 0);
}

void reName(GirlP girlP){
    girlP->name = "lisa";
}

void main(){
    Girl girl;
    girl.name = "lily";
    girl.age = 12;
    girl.sayHi = sayHi;
    GirlP girlP = &girl;
    reName(girlP);
    girl.sayHi(girlP->name);
    getchar();
}

你可能感兴趣的:(C语言基础03:结构体&结构体与指针)