当前位置:首页 > 嵌入式 > 嵌入式云IOT技术圈
[导读]     做了挺久的开发,对于C这种东西,我不敢说自己已经精通了,毕竟还是有许多细节在学习的过程中会遗忘,然后再通过实践慢慢去一点点捡回来。所以只能算是熟练级别。      Linux内核的实现博大精深,它大部分都是由C语言实现的,从offsetof的实现到后面的co

     做了挺久的开发,对于C这种东西,我不敢说自己已经精通了,毕竟还是有许多细节在学习的过程中会遗忘,然后再通过实践慢慢去一点点捡回来。所以只能算是熟练级别。
     Linux内核的实现博大精深,它大部分都是由C语言实现的,从offsetof的实现到后面的container_of,为什么通过结构体的的成员就能获得整个结构体的指针呢?这就得益于offsetof宏的实现。关于这个宏,前面的博文也有讲解,但不够深入,今天的这个例子,足以对结构体本身的原理大彻大悟,我们来看下面这个例子:
#include <stdio.h>
//32位系统上,结构体在没指定对齐的时候,默认以四字节进行对齐 
typedef struct __ST
{
int id ; //4
char *name ; //4
float math ;//4
}ST;
int main()
{
ST st ;
//获取结构体的第一个元素的首地址 
int *ptr_0 = (int *)(&st);
printf("st:   %p    ptr:   %p \n",&st,ptr_0);
//对结构体第一个元素赋值 
*ptr_0 = 100 ;
printf("*ptr_0 = %d\n",*ptr_0);
//获取结构体的第二个元素的首地址,因为第二个元素是一级指针,所以需要用一个二级指针来接 
char **ptr_1 = (char **)((int)&st+4) ;
printf("ptr_1:%p\n",ptr_1);
//对结构体的第二个元素赋值 
*ptr_1 = "hello world";
printf("ptr_1:%s\n",*ptr_1);
//获取结构体的第三个元素的首地址,根据对齐原则偏移算出第三个元素的地址 
float *ptr_2 = (float *)((int)&st+8) ;
printf("ptr_2:%p \n",ptr_2);
//对结构体的第三个元素进行赋值 
*ptr_2 = 96.78 ;
printf("ptr_2:%.2f \n",*ptr_2);
//输出结构体中所有成员的值 
printf("st.id = %d   st.name = %s   st.math =%.2f\n",st.id,st.name,st.math);
    return 0;
}
       这里的根据对齐原则算出来的偏移量其实其实不就是offsetof宏的原理吗?
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
       往后继续看待链表,函数指针,等等与结构体有关的概念,瞬间觉得一幕了然,彻底打通了这条曾经学习的阻塞道路。


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式Linux开发中,快速获取系统状态信息是调试和监控的关键能力。本文整理了7个高频使用的C语言代码片段,涵盖内存、CPU温度、文件操作等核心场景,帮助开发者高效实现系统状态采集。

关键字: 嵌入式Linux C语言

作为当前最广泛应用的对称加密算法,AES-128凭借其128位密钥长度和10轮加密迭代,在保障数据安全的同时保持高效性能。本文将深入解析AES-128的流式实现原理,并提供经过优化的C语言实现方案,特别针对长数据流处理场...

关键字: AES-128 C语言

在C语言的指针宇宙中,函数指针如同一个神秘的传送门,它打破了传统函数调用的静态边界,让程序在运行时能够动态选择执行路径。这种机制不仅赋予代码前所未有的灵活性,更在系统编程、嵌入式开发等场景中扮演着关键角色。

关键字: 函数指针 C语言

在嵌入式系统、数据库开发和多媒体处理等场景中,二进制文件的随机访问是核心需求。C标准库提供的fseek和ftell函数组合,为高效定位文件位置提供了轻量级解决方案。本文通过代码示例和性能对比,解析其实现原理与最佳实践。

关键字: 二进制文件 C语言

结构体作为C/C++中组织异构数据的核心方式,其内存布局直接影响程序性能。本文通过量化实验对比不同对齐策略的内存占用差异,结合编译器指令实现精准优化。

关键字: 结构体 C语言 编译器

在C语言中,字符串操作是程序设计中非常基础且重要的部分。由于C语言本身没有内置的字符串类型,字符串通常以字符数组或字符指针的形式出现。因此,掌握常见的字符串操作函数的实现原理对于深入理解C语言的内存管理、指针操作和字符串...

关键字: C语言

在C语言编程中,循环结构是处理重复任务的核心工具,而break和continue则是控制循环流程的关键指令。虽然两者都用于改变循环的正常执行路径,但它们的行为和适用场景存在本质差异。

关键字: C语言 编程

在C语言编程中,头文件(.h)是代码组织与模块化的核心工具,而宏定义(#define)作为预处理指令,能够显著提升代码的可读性、可移植性和可维护性。

关键字: C语言

在嵌入式实时系统中,多线程编程通过并发执行提升资源利用率,但共享资源访问冲突会引发数据竞争与死锁。锁机制作为核心同步手段,其选择直接影响系统实时性与可靠性。本文从嵌入式场景出发,分析常见锁机制特性,并提出优化策略。

关键字: C语言 多线程编程 嵌入式系统

在C语言编程中,头文件是代码组织和模块化的重要工具。宏定义作为预处理阶段的核心特性,能够显著提升代码的灵活性、可读性和可移植性。一个精心设计的头文件库,配合恰当的宏定义,可以让代码更加优雅高效。

关键字: C语言
关闭