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

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

type A:

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span> Student
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

使用方法:

<span style="color:#000000"><code class="language-c">		Stu exam<span style="color:#999999">;</span>

</code></span>

type B:

省略了struct后面的内容

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span>
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

使用方法:

<span style="color:#000000"><code class="language-c">		Stu exam<span style="color:#999999">;</span>

</code></span>

type C:

省略了最后分号前的定义

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span> stu
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span><span style="color:#999999">;</span>
</code></span>

使用方法:

<span style="color:#000000"><code class="language-c">		<span style="color:#c678dd">struct</span> Student exam<span style="color:#999999">;</span>

</code></span>

注意:这种方法编译器可能会警告,但是能够运行且正常读取数据不发生段错误。
图1
type D:不使用typedef的情况

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">struct</span> Student
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

使用方法:

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">struct</span> Student exam<span style="color:#999999">;</span>

</code></span>

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">struct</span>
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

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

<span style="color:#000000"><code>struct Student exam;

</code></span>
  • 1
  • 2

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

热菜来了:

A结构体指针

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span> Student
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">,</span><span style="color:#669900">*</span>pStu<span style="color:#999999">;</span>
</code></span>

使用方法:

<span style="color:#000000"><code class="language-c">pStu exam1<span style="color:#999999">;</span>
Stu exam2<span style="color:#999999">;</span>
exam1 <span style="color:#669900">=</span> <span style="color:#669900">&</span>exam2<span style="color:#999999">;</span>
exam2<span style="color:#999999">.</span>a <span style="color:#669900">=</span> <span style="color:#98c379">1</span><span style="color:#999999">;</span>
<span style="color:#61aeee">printf</span><span style="color:#999999">(</span><span style="color:#669900">"%d"</span><span style="color:#999999">,</span>exam1<span style="color:#669900">-></span>a<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#5c6370">//输出为1</span>
</code></span>

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

<span style="color:#000000"><code class="language-c">Stu <span style="color:#669900">*</span>exam1<span style="color:#999999">;</span>
Stu exam2<span style="color:#999999">;</span>
exam1 <span style="color:#669900">=</span> exam2<span style="color:#999999">;</span>
exam2<span style="color:#999999">.</span>a <span style="color:#669900">=</span> <span style="color:#98c379">1</span><span style="color:#999999">;</span>
<span style="color:#61aeee">printf</span><span style="color:#999999">(</span><span style="color:#669900">"%d"</span><span style="color:#999999">,</span>exam1<span style="color:#669900">-></span>a<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#5c6370">//输出为1</span>
</code></span>

结构体数组的指针使用

<span style="color:#000000"><code class="language-c">Stu exam<span style="color:#999999">[</span><span style="color:#98c379">4</span><span style="color:#999999">]</span><span style="color:#999999">;</span>
pStu p<span style="color:#999999">;</span>
p <span style="color:#669900">=</span> exam<span style="color:#999999">;</span>
p <span style="color:#669900">+</span><span style="color:#669900">=</span><span style="color:#98c379">2</span><span style="color:#999999">;</span><span style="color:#5c6370">//等价于p = exam[1]</span>
</code></span>

多维结构体

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

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span> Student
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
	    <span style="color:#c678dd">void</span> <span style="color:#999999">(</span><span style="color:#669900">*</span>fun<span style="color:#999999">)</span><span style="color:#999999">(</span><span style="color:#c678dd">int</span> a<span style="color:#999999">)</span><span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

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

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">void</span> <span style="color:#61aeee">foo</span><span style="color:#999999">(</span><span style="color:#c678dd">int</span> i<span style="color:#999999">)</span><span style="color:#999999">{</span>
	<span style="color:#61aeee">printf</span><span style="color:#999999">(</span><span style="color:#669900">"%d"</span><span style="color:#999999">,</span>i<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span>
</code></span>
<span style="color:#000000"><code>	Stu exam;
	exam.fun = foo;//
	exam.fun(1);//调用引用的函数,输出1
</code></span>

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

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

<span style="color:#000000"><code class="language-c">    <span style="color:#c678dd">typedef</span> <span style="color:#c678dd">struct</span> Student
    <span style="color:#999999">{</span>
	    <span style="color:#c678dd">int</span> a<span style="color:#999999">;</span>
		   <span style="color:#c678dd">struct</span> Student <span style="color:#669900">*</span>stu_exam<span style="color:#999999">;</span>
    <span style="color:#999999">}</span>Stu<span style="color:#999999">;</span>
</code></span>

用法:

<span style="color:#000000"><code class="language-c">Stu exam<span style="color:#999999">;</span>
Stu child<span style="color:#999999">;</span>
child<span style="color:#999999">.</span>a <span style="color:#669900">=</span> <span style="color:#98c379">1</span><span style="color:#999999">;</span>
exam<span style="color:#999999">.</span>stu_exam<span style="color:#669900">=</span>child<span style="color:#999999">;</span><span style="color:#5c6370">//exam内的“本身”是结构体child</span>
</code></span>

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

<span style="color:#000000"><code class="language-c">exam<span style="color:#999999">.</span>stu_exam<span style="color:#999999">.</span>a?
</code></span>

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

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

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

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">static</span> <span style="color:#c678dd">struct</span> file_operations hello_flops <span style="color:#669900">=</span> <span style="color:#999999">{</span>
    <span style="color:#999999">.</span>owner  <span style="color:#669900">=</span>   THIS_MODULE<span style="color:#999999">,</span>
    <span style="color:#999999">.</span>open   <span style="color:#669900">=</span>   hello_open<span style="color:#999999">,</span>     
    <span style="color:#999999">.</span>write  <span style="color:#669900">=</span>   hello_write<span style="color:#999999">,</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>
</code></span>

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

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">static</span> <span style="color:#c678dd">struct</span> file_operations hello_flops<span style="color:#999999">;</span>
hello_flops<span style="color:#999999">.</span>owner  <span style="color:#669900">=</span>   THIS_MODULE<span style="color:#999999">;</span>
hello_flops<span style="color:#999999">.</span>open   <span style="color:#669900">=</span>   hello_open<span style="color:#999999">;</span>
hello_flops<span style="color:#999999">.</span>write  <span style="color:#669900">=</span>   hello_write<span style="color:#999999">;</span>
</code></span>

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

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

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">struct</span> button_desc <span style="color:#999999">{</span>
	<span style="color:#c678dd">int</span> gpio<span style="color:#999999">;</span>
	<span style="color:#c678dd">int</span> number<span style="color:#999999">;</span>
	<span style="color:#c678dd">char</span> <span style="color:#669900">*</span>name<span style="color:#999999">;</span>	
	<span style="color:#c678dd">struct</span> timer_list timer<span style="color:#999999">;</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>

<span style="color:#c678dd">static</span> <span style="color:#c678dd">struct</span> button_desc buttons<span style="color:#999999">[</span><span style="color:#999999">]</span> <span style="color:#669900">=</span> <span style="color:#999999">{</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH2</span><span style="color:#999999">(</span><span style="color:#98c379">0</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">0</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY0"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH2</span><span style="color:#999999">(</span><span style="color:#98c379">1</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">1</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY1"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH2</span><span style="color:#999999">(</span><span style="color:#98c379">2</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">2</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY2"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH2</span><span style="color:#999999">(</span><span style="color:#98c379">3</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">3</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY3"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH3</span><span style="color:#999999">(</span><span style="color:#98c379">0</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">4</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY4"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH3</span><span style="color:#999999">(</span><span style="color:#98c379">1</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">5</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY5"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH3</span><span style="color:#999999">(</span><span style="color:#98c379">2</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">6</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY6"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
	<span style="color:#999999">{</span> <span style="color:#61aeee">S5PV210_GPH3</span><span style="color:#999999">(</span><span style="color:#98c379">3</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#98c379">7</span><span style="color:#999999">,</span> <span style="color:#669900">"KEY7"</span> <span style="color:#999999">}</span><span style="color:#999999">,</span>
<span style="color:#999999">}</span><span style="color:#999999">;</span>
</code></span>

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值