打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
中阶C语言 结构体(typedef用法、多维结构体、指针、内嵌函数、赋值)

//wings20200306:

结构体中内嵌自身,这个地方没表达清楚,且意义何在?

先上冷菜:复习结构体样式

type A:

多年工作经验告诉我这种方法最为标准实用,墙裂推荐

    typedef struct Student    {	    int a;    }Stu;

使用方法:

		Stu exam;

type B:

省略了struct后面的内容

    typedef struct    {	    int a;    }Stu;

使用方法:

		Stu exam;

type C:

省略了最后分号前的定义

    typedef struct stu    {	    int a;    };

使用方法:

		struct Student exam;

注意:这种方法编译器可能会警告,但是能够运行且正常读取数据不发生段错误。

type D:不使用typedef的情况

typedef可以自定义化名称,不使用它相当于直接操作原生的结构体。
1.将typeA中的typedef去掉,此时Stu已经没意义了,注意不可以使用struct Stu exam

    struct Student    {	    int a;    }Stu;

使用方法:

struct Student exam;

2.将typeB中的typedef去掉
这是直接创建结构体变量的形式,只能使用一次,显然在实战中基本没有什么用处。

    struct    {	    int a;    }Stu;

3.将typeC中的typedef去掉
百度百科收录了这种写法,也是比较标准的,但是本人不推荐使用
    typedef struct stu
    {
    int a;
    };
使用方法:

struct Student exam;

冷菜总结:实际应用上使用TYPE A的场景极其繁多,真心只记住它就行。

热菜来了:

A结构体指针

定义:
拿最经典的TYPE A,在分号前面增加了指针

    typedef struct Student    {	    int a;    }Stu,*pStu;

使用方法:

pStu exam1;Stu exam2;exam1 = exam2;exam2.a = 1;printf("%d",exam1->a);//输出为1

也可以不改变TYPE A
使用方法:

Stu *exam1;Stu exam2;exam1 = exam2;exam2.a = 1;printf("%d",exam1->a);//输出为1

结构体数组的指针使用

Stu exam[4];pStu p;p = exam;p +=2;//等价于p = exam[1]

多维结构体

参考结构体数组的使用,区别在于之前+1就指向下一个结构体成员。这里的+1理论上就是结构体单位大小所占内存空间的偏移。
复杂式结构体TYPE I:内有函数指针

继续拿最经典的TYPE A,加入函数指针

    typedef struct Student    {	    int a;	    void (*fun)(int a);    }Stu;

使用之前先定义一个引用的函数

void foo(int i){	printf("%d",i);}
	Stu exam;	exam.fun = foo;//	exam.fun(1);//调用引用的函数,输出1

这个函数指针有点low,来个再复杂的,其实就是指针方面的知识了,还是挺有用的,直接贴图

复杂式结构体TYPE II:内部竟有本身
就是这么神奇,继续拿最经典的TYPE A,加入本身

    typedef struct Student    {	    int a;		   struct Student *stu_exam;    }Stu;

用法:

Stu exam;Stu child;child.a = 1;exam.stu_exam=child;//exam内的“本身”是结构体child

那么怎么读取child中的a元素值?

exam.stu_exam.a?

显然不对,正确的做法是需要一个Stu类型的容器来装child,这是抽象的,实体实现就是定义一个Stu指针指向child

Stu *p;p = exam.stu_exam;//注意这里使用了=,如果stu_exam是指针类型的,应该p = &exam.stu_exam;printf("%d",p->a);//输出a,大功告成

复杂式结构体TYPE III:以“.”开头

static struct file_operations hello_flops = {    .owner  =   THIS_MODULE,    .open   =   hello_open,         .write  =   hello_write,};

这是结构体初始化的一种方式,.的功能还是访问参数。
按照通用的方法,可以写成这样

static struct file_operations hello_flops;hello_flops.owner  =   THIS_MODULE;hello_flops.open   =   hello_open;hello_flops.write  =   hello_write;

这种样式可以说把2步缩成一步了,省事并且更直观。

这个声明采用了标记化结构初始化语法。这种写法是值得采用的,因为它使驱动程序在结构的定义发生变化时更具有可移植性,并且使代码更加紧凑且易读。标记化的初始化方法允许对结构成员进行重新排列。在某些场合下,将频繁被访问的成员放在相同的硬件缓存行上,将大大提高性能。
复杂式结构体TYPE V:缺省赋值结构体成员

struct button_desc {	int gpio;	int number;	char *name;		struct timer_list timer;};static struct button_desc buttons[] = {	{ S5PV210_GPH2(0), 0, "KEY0" },	{ S5PV210_GPH2(1), 1, "KEY1" },	{ S5PV210_GPH2(2), 2, "KEY2" },	{ S5PV210_GPH2(3), 3, "KEY3" },	{ S5PV210_GPH3(0), 4, "KEY4" },	{ S5PV210_GPH3(1), 5, "KEY5" },	{ S5PV210_GPH3(2), 6, "KEY6" },	{ S5PV210_GPH3(3), 7, "KEY7" },};

首先定义了button_desc的结构体类型,然后申请了buttons结构体组,在进行赋值的时候发现内容不够完整,{}内是3个变量,原定义是4个。结果一样是可以使用的,指针不越界,因为系统已经申请了内存,只不过timer部分的内存都是空的。

未完待续

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
《C语言程序设计教程(第4版)》第10章结构体与共用体
C语言程序设计案例式教程-第9章 结构体
结构体中定义函数指针
struct与 typedef
C语言指针的长度和类型深入分析
为什么很多人编程喜欢用typedef?如何避免滥用?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服