13 C结构体

1、why结构体?

#include <stdio.h>

int main()
{
    /*
     * 什么是结构体?
     * 结构体时构造类型的一种
     *
     * 构造类型前面我们已经学习过了数组:
     * 数组的作用是用于存储一组相`同类型`的数据
     * 结构体的作用是用于存储一组`不同类型`的数据
     *
     * 保存一个人的信息
     * 姓名/年龄/身高 ...
     * char *
     * int
     * double
     *
     * 如何定义结构体变量
     * 1.先定义结构体类型
     * 2.通过结构体的类型定义结构体变量
     *
     * 如何定义结构体类型?
     * struct 结构体类型名称{
     *   数据类型 属性名称;
     *   数据类型 属性名称;
     *   ... ...
     * };
     *
     * 如何定义结构体变量
     * struct 结构体类型名称 变量名称;
     *
     * 如何访问结构体的属性
     * 结构体变量名称.结构体属性名称;
     */
    // 1.定义结构体类型
    struct Person{
        char *name; // name我们称之为结构体的属性名称
        int age; // age也称之为结构体的属性名
        double height; // height也称之为结构体的属性名称
    };
    // 2.定义结构体变量
    struct Person p;

    // 3.使用结构体变量
//    int ages[3] = {1, 3, 5};
//    ages[0] = 1;
    // 格式: 结构体变量名称.结构体属性名称
    p.name = "msh";
    p.age = 24;
    p.height = 2.0;
    printf("name = %s\n", p.name);
    printf("age = %i\n", p.age);
    printf("height = %lf\n", p.height);
    return 0;
}

2、结构体的初始化

#include <stdio.h>

int main()
{
    /*
     * 结构体变量初始化的几种方式
     * 1.定义的同时初始化
     * 2.先定义再初始化
     */
    // 1.定义结构体类型
    struct Dog{
        char *name;
        int age;
        double height;
    };
    // 2.定义结构体变量
    // 2.1先定义后初始化
//    struct Dog dd;
//    dd.name = "ww";
//    dd.age = 1;
//    dd.height = 1.5;

    // 2.2定义的同时初始化
//    struct Dog dd = {"ww", 1, 1.5};
    // 注意点: 如果在定义的同时初始化, 那么初始化的顺序必须和结构体类型中的顺序一致
//    struct Dog dd = {1, "ww", 1.5};
//    struct Dog dd = {.age = 1, .name = "ww", .height = 1.5};
//    printf("name = %s\n", dd.name);
//    printf("name = %i\n", dd.age);
//    printf("name = %lf\n", dd.height);

    // 3.特殊的初始化方式
    // 数组只能在定义的同时完全初始化, 不能先定义再完全初始化
    // 但是结构体既可以在定义的同时完全初始化, 也可以先定义再完全初始

//    int ages[3] = {1, 3, 5};
//    int ages[3];
//    ages = {1, 3, 5};

    // 企业开发不推荐这样编写
     struct Dog dd;
     dd = (struct Dog){"ww", 1, 1.5};
     printf("name = %s\n", dd.name);
     printf("name = %i\n", dd.age);
     printf("name = %lf\n", dd.height);

    return 0;
}

3、结构体的几种定义方式

#include <stdio.h>

int main()
{
    /*
     * 定义结构体变量的几种方式
     * 1.先定义结构体类型, 再定义结构体变量
     * 2.定义结构体类型的同时定义结构体变量
     * 3.定义结构体类型的同时省略结构体名称, 同时定义结构体变量
     */
    // 1.先定义结构体类型, 再定义结构体变量
    /*
    struct Person{
        char *name;
        int age;
        double height;
    };
    struct Person p1;
    struct Person p11;
    */

    // 2.定义结构体类型的同时定义结构体变量
    /*
    struct Person{
        char *name;
        int age;
        double height;
    } p2;
    p2.name = "msh";
    printf("name = %s\n", p2.name);
    struct Person p22;
    */
    // 3.定义结构体类型的同时省略结构体名称, 同时定义结构体变量
    // 匿名结构体
    // 特点: 结构体类型只能使用一次
    struct{
        char *name;
        int age;
        double height;
    } p3;
    p3.name = "yl888";
    printf("name = %s\n", p3.name);
    return 0;
}
#include <stdio.h>

struct Person{
    char *name;
    int age;
    double height;
};
int main()
{
    /*
     * 结构体类型的作用域
     * 和变量的作用域一样
     */
    // 1.定义一个结构体类型
    {
//        struct Person{
//            char *name;
//            int age;
//            double height;
//        };
        struct Person p1;
    }
    struct Person p3;
    return 0;
}
void test(){
    // 找不到Person这个结构体类型
     struct Person p2;
}
#include <stdio.h>

int main()
{
    /*
     * 结构体数组
     * 就是定义个数组保存结构体变量
     */
    struct Person{
        char *name;
        int age;
        double height;
    };
//    struct Person p1 = {"msh", 24, 1.90};
//    struct Person p2 = {"zs", 22, 1.2};
//    struct Person p3 = {"ls", 33, 1.4};
//    struct Person p4 = {"ww", 56, 1.8};
    // 数据类型 数组名称[元素个数];
//    struct Person ps[4];
//    ps[0] = p1;
//    ps[1] = p2;
//    ps[2] = p3;
//    ps[3] = p4;

//    struct Person ps[4] = {p1, p2, p3, p4};
     struct Person ps[4] ={
         {"msh", 24, 1.90},
         {"zs", 22, 1.2},
         {"ls", 33, 1.4},
         {"ww", 56, 1.8},
     };

    return 0;
}

int main()
{
    /*
     * 结构体内存分析
     * 注意点:
     * 给整个结构体变量分配存储空间和数组一样, 从内存地址比较大的开始分配
     * 给结构体变量中的属性分配存储空间也和数组一样, 从所占用内存地址比较小的开始分配
     *
     * 注意点:
     * 和数组不同的是, 数组名保存的就是数组首元素的地址
     * 而结构体变量名, 保存的不是结构体首属性的地址
     */
    /*
    struct Person{
        int age;
        int score;
    };
    struct Person p;
    // 看上去, 好像是所有属性类型的总和
    printf("sizeof = %i\n", sizeof(p)); // 8
    // 数组名称保持的就是数组首元素的地址
    // 结构体的名称是否保存的也是第一个属性的地址
    // 通过观察得出一个结论: 结构体变量的名称并没有保存结构体首属性的地址
    printf("p = %p\n", p); // p = 00000077
    printf("&p = %p\n", &p); // &p = 0060FEA8
    printf("&p.age = %p\n", &p.age); // &p.age = 0060FEA8
    printf("&p.score = %p\n", &p.score); // &p.score = 0060FEAC
    */

    struct Person{
        int age; // 4
//        char ch; // 1
        double score; // 8
        char ch;
    };
    struct Person p;
    // 结构体在分配内存的时候, 会做一个内存对齐的操作
    // 会先获取所有属性中占用内存最大的属性的字节
    // 然后再开辟最大属性字节的内存给第一个属性, 如果分配给第一个属性之后还能继续分配给第二个属性, 那么就继续分配
    // 如果分配给第一个属性之后, 剩余的内存不够分配给第二个属性了, 那么会再次开辟最大属性直接的内存, 再次分配
    // 一次类推
    printf("sizeof = %i\n", sizeof(p)); // 16
    return 0;
}

#include <stdio.h>

int main()
{
    /*
     * 结构体指针
     * 因为结构体变量也会分配内存空间, 所以结构体变量也有内存地址, 所以也可以使用指针保存结构体变量的地址
     *
     * 规律:
     * 定义指向结构体变量的指针的套路和过去定义指向普通变量的一样
     *
     * 如果指针指向了一个结构体变量, 那么访问结构体变量的属性就有3种方式
     * 结构体变量名称.属性名称;
     * (*结构体指针变量名称).属性名称;
     * 结构体指针变量名称->属性名称;
     */

    struct Person{
        char *name;
        int age;
        double height;
    };
    struct Person per = {"msh", 24, 1.9};
    struct Person *p;
    p = &per;
//    printf("per.name = %s\n", per.name);
//    printf("per.name = %s\n", (*p).name);
    printf("per.name = %s\n", p->name);
    return 0;
}

#include <stdio.h>

int main()
{
    /*
     * 结构体嵌套定义
     * 结构体的属性可以又是一个结构体
     *
     * 提高代码的复用性
     */
    /*
    struct Person{
        char *name;
        int age;

        // 出生年月
        int year;
        int month;
        int day;

        // 死亡日期
        int year2;
        int month2;
        int day2;

        // 读幼儿园日期
        // 读小学日期
        // 读中学日期
        // 读大学日期
        // 工作日期
        // 结婚日期
        // ... ...
    }
    */
    // 1.定义了一个日期的结构体类型
    struct Date{
        int year;
        int month;
        int day;
    };
    // 2.定义一个人的结构体类型
    struct Person{
        char *name;
        int age;
        struct Date birthday;
    };
    struct Person p = {"msh", 24, {2020, 12, 12}};

    printf("name = %s\n", p.name);
    printf("name = %i\n", p.age);
    printf("name = %i\n", p.birthday.year);
    printf("name = %i\n", p.birthday.month);
    printf("name = %i\n", p.birthday.day);

    return 0;
}

#include <stdio.h>

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

void test(struct Person per);

int main()
{
    /*
     * 结构体和函数
     * 虽然结构体是构造类型, 但是结构体变量之间的赋值
     * 和基本数据类型赋值一样, 是拷贝
     */

    // 注意点: 定义结构体类型不会分配存储空间
    // 只有定义结构体变量才会分配存储空间
    /*
    struct Person{
        char *name;
        int age;
    };
    struct Person p1 = {"msh", 24};
    struct Person p2;
    p2 = p1;
    p2.name = "zs";
    printf("p1.name = %s\n", p1.name); // msh
    printf("p2.name = %s\n", p2.name); //  zs
    */

    struct Person p1 = {"msh", 24};
    printf("p1.name = %s\n", p1.name); // msh
    test(p1);
    printf("p1.name = %s\n", p1.name); // msh
    return 0;
}
void test(struct Person per){
    per.name = "zs";
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 1、如果不是为了繁衍,其实男人会更愿意和男人呆在一起? 前段时间听到两个男同事在办公室吐槽和女朋友相处的种种,...
    Too茜茜阅读 363评论 0 2
  • 他人各有各的忧愁,我也曾未好受。 也许对别人来说,闭嘴,缄默不语就是最大的善意。 我不想装作善解人意去了解每一个人...
    慕白橙阅读 150评论 0 0
  • 简评电影《坏孩子的天空》 本片虽然号称青春电影,但却没有丝毫青春电影应有的明快与清新,相反,导演北野武将视点聚焦在...
    冰雪声阅读 359评论 0 0