当前位置: 首页 > news >正文

嵌入式c学习第十一天

c语言结构体:struct(structure的缩写)

定义格式:

struct 结构体名称
{
	数据类型 成员名称; 
	数据类型 成员名称; 
	数据类型 成员名称; 

};				//复合语句后面的分号,不可以省略 

结构体不应该包含不完整的类型或者函数类型,结构体中不应该包含结构体本身,但是结构体可以包含指向该结构体类型的指针。

构造的结构体类型不占内存,只有使用该类型创建变量实才会得到内存空间

成员赋值:连续赋值,和单独赋值

成员访问:

①通过.访问:后缀运算符 . 的第一个操作对象应该是一个结构体或者联合体类型,第二个操作对象是成员名称

②通过->访问:后缀运算符-> 的第一个操作对象是指向结构体类型的指针,第二个操作对象是成员名称

#include <stdio.h>

// 定义一个结构体数据类型,此时不占内存 
struct Person 
{
    char name[20];
    int age;
    char sex[10];
};

int main() 
{
	//定于一一个结构体变量,此时变量p1会得到内存空间 
    struct Person p1;
    
    //通过后缀运算符点访问成员 
    p1.age = 20;
    printf("p1.age=%d\n", p1.age);
	
	//定义一个指针变量指向该结构体类型的空间(堆内存或者变量地址)
	struct Person *p = &p1;
	
	p->age = 25;					//通过->访问 
	printf("p->age=%d\n", p1.age);
	
	(*p).age = 27; 					//通过间接得到地址下的变量,使用点访问成员 
	printf("(*p).age=%d\n", p1.age);
	
    return 0;
}

结构体的空间大小:32位系统中未考虑CPU运行效率,寻址主要是以4字节为主,即当数据不够4字节宽度时,系统默认提供4字节内存,方便CPU寻址,这种方式也叫字节对齐(空间换时间)

使用 #pragma  pack(1),可以取消字节对齐

#include <stdio.h>

// 32位系统默一次性寻址4字节 
struct Person1 
{
    int i;                 //4                  4
    char j;				   //1                  4 
    char *p;               //4                  4 
    long a[100];           //400         		400
    char b[2];             //2                  4
    char *q;               //4——415           4——420 
};

#pragma  pack(1)     //取消字节对齐 

struct Person2 
{
    int i;                 //4                  4
    char j;				   //1                  4 
    char *p;               //4                  4 
    long a[100];           //400         		400
    char b[2];             //2                  4
    char *q;               //4——415           4——420 
};

#pragma  pack()      //恢复字节对齐 

struct Person3
{
    int i;                 //4                  4
    char j;				   //1                  4 
    char *p;               //4                  4 
    long a[100];           //400         		400
    char b[2];             //2                  4
    char *q;               //4——415           4——420 
};


int main() 
{
	struct Person1 pes1;
	printf("pes memory is %d bytes\n", sizeof(pes1));   //420 
	
	struct Person2 pes2;
	printf("pes memory is %d bytes\n", sizeof(pes2));   //415
	
	struct Person3 pes3;
	printf("pes memory is %d bytes\n", sizeof(pes3));   //415
	
    return 0;
}

变量定义

#include <stdio.h>

//此方式,data1,data2都是结构体变量,且后续不能在定义此结构体变量 
struct 
{
    int i;                 
    char j;				  
    char *p;             
    long a[100];           
    char b[2];             
    char *q;               
}data1, *data2;     //data1 普通变量,data2 指针变量 

int main() 
{
	(&data1)->i = 20;
	printf("(&data1)->i is %d\n", data1.i);   //420 
	
    return 0;
}

别名定义:typedef(type define缩写)

使用格式:typedef 数据类型  别名;如:typedef   unsigned char    uint8_t(别名末尾加_t)

#include <stdio.h>

typedef struct student
{
    int i;                 
    char j;				  
    char *p;             
    long a[100];           
    char b[2];             
    char *q;               
}pes_t;    


int main() 
{	
	//定于一个结构体变量
	struct student data1; 
	pes_t data2;
	
	//定义结构体数组,并访问访问内部成员 
	struct student arr[10];
	arr[0].i = 20;
	
	//定义结构体指针数组,并访问访问内部成员 
	struct student  *str[10]; 
	
	str[0]->i = 30; 
	
    return 0;
}

c语言联合体:union,用同一块内存存储不同类型数据,这些数据是互斥的,不能同时存在,联合体内存空间就是成员中数据宽度最大的那个

定义类型

 union  联合体名称

 {

    数据类型 成员名称;

    数据类型 成员名称;

    数据类型 成员名称;

 };

成员访问

①通过.访问   类型.成员名称

②通过->访问  指向结构体类型的指针->成员名称

联合体也遵循字节对齐原则

通过联合体判断大端还是小端存储

#include <stdio.h>

union             //创建联合体类型
{
	int a;
	char b;
}outmod;          //定义联合体变量


int main() 
{	
	outmod.a = 0x12345678;
	
	printf("%#x\n", outmod.b);
	
	if(0x12 == outmod.b)
	{
		printf("采用大端存储模式"); 
	}
	else
	{
		printf("采用小端存储模式"); 
	}
	
    return 0;
}

枚举:enum,每个成员都必须是整形,吧一些没有意义的整数起一个有意义的名称,利用该名称就相当于使用该常量,提高程序的可读性

#include <stdio.h>

enum
{
	red,          //第一个元素未被初始化默认为0 
	blue,
	yellow=5,     //对当前元素进行初始化 
	green	      //当前元素的值是上一个元素的值+1 = 6 
};

int main() 
{	
	printf("red is %d\n", red);
	printf("green is %d\n", green);
	
    return 0;
}

http://www.dtcms.com/a/107699.html

相关文章:

  • CMake 中的置变量
  • 在服务器里面磁盘分区很简单吗?
  • 51单片机的五类指令(三)——逻辑操作类指令
  • 【图形API】片段着色器自动计算LOD
  • 蓝桥杯嵌入式16届—— LED模块
  • 【ABAP】REST/HTTP技术(一)
  • 进程间的通信
  • 批量删除 txt/html/json/xml/csv 等文本文件中的重复行
  • 2025年Axure RP9无法免费使用Axure Cloud的解决方案
  • IEOSE北京国际教育留学展 留学盛宴4月亮相国会
  • c++进阶之----orderedmap和unorderedmap
  • 不同向量数据库(FAISS / Pinecone / Weaviate)在 RAG 中的优缺点
  • 生成式AI应用带来持续升级的网络安全风险
  • Linux系统CentOS 6.3安装图文详解
  • 嵌入式调试进阶:从手动到自动的HardFault破案指南
  • qt实现功率谱和瀑布图
  • Kubernetes APIServer 可观测最佳实践
  • Telnet协议详解:本质与操作逻辑
  • 路由协议分类精讲
  • TrollStore(巨魔商店)介绍及操作手册
  • C 标准库 - `<ctype.h>`
  • Vue el-table-column内el-tooltip识别换行符 \n
  • Mysql的安装
  • java 使用 spring AI 实战MCP
  • centos-LLM+EmbeddingModel+VectorDB-简单模型
  • Aliee,Bengio and Theis:细胞数据上的因果机器学习
  • 代理模式-spring关键设计模式,bean的增强,AOP的实现
  • Spring SpringBoot 细节总结
  • 【ROS】 CMakeLists 文件详解
  • 大数据Spark(五十六):Spark生态模块与运行模式