嵌入式Linux C(十二)——复合数据类型

简介: 嵌入式Linux C(十二)——复合数据类型

一、struct结构体


struct 定义结构体类型:


第一个字母大写;

{}后面有;号

结构体名一定能体现结构体的作用(自注释性)

最好写在全局,或者写在头文件(结构体定义在函数内部,只能由该函数调用)

不可以保存函数,但是可以保存函数指针

用.或者->访问结构体变量的成员

初始化(野指针问题、直接给数组名赋值(指针常量))

结构体之间的赋值:浅拷贝;—>深拷贝

浅拷贝(自己写)

释放两次

0a2653c851af460fa595bd959398a8f1.png

深拷贝?

2d65d23f6d4748949b924e4057485923.png

//深拷贝
void copy_struct(struct student * s1, const struct Student *s2)
{
  (*s1).num = (*s2).num;
  (*s1).age = (*s2).num;
  int len = strlen((*s2).num);
  (*s1).name = (char *)malloc(sizeof(char) * len + 1);//+1为了'/0'
  strcpy((*s1).name,(*s2).name); 
}


struct Student
{
  int num;
  char name[30];
  //char *name;
  int age;
  void (*fun)();
};
void print()
{
  printf("hello world");
}
//初始化:
struct Student stu = {1,"zhangsan",12,printf};
struct Student stu2 = {.num = 1,.name = "zhangsan",.age = 12,.fun = print};
//定义结构体指针
struct Student *pstu = &stu;   
struct Student stu2 = {
  .num = 1,
  .name = "zhangsan",
  .age = 12,
  .fun = print
};
printf("stu.num = %d\n",stu.num);
printf("stu.num = %d\n",(*pstu).num);//`()`一定加,优先的.高,所以加上括号
printf("stu.name = %d\n",(*pstu).name);
printf("stu.num = %d\n",pstu->num);//`->`前后不能有空格
printf("stu.num = %d\n",(&stu)->num);
struct Student stu3;
scanf("%d",&(stu.num));
//stu.name = (char *)malloc(sizeof(char) * 100);
//if(NULL == syu.name)
//{
//  printf("malloc error!\n");
//  exit(1);
//}
//scanf("%s",stu.name);
//stu.name = "zhangsan";//数组名不能赋值,是常量
strcpy(stu.name,zhangsan"")
scanf("%d"&(stu.age));
//free(stu.name);
struct Student stu4;
//stu4 = stu;
copy_struct(&stu4,&stu3)
free(stu3.name);
free(stu4.name);


1. 使用注意事项:


字对齐,导致的内存空洞,将相同类型放在一起


结构体的作用:封装数据(打包数据) — 抽象数据


字(4个字节)对其的方式(默认处理方式)(等于4个字节)

ch1 —> 4

num —> 4

ch2 —> 4

首先会为第一数据分配一个字,再看下一时,分析上一个剩余空间是否够用,不够用则新开辟空间

双字(8个字节)对其的方式(默认处理方式)(大于4个字节)


struct node
{
  char ch1;
  int num;
  char ch2;
};
//特殊
struct node
{
  char ch1;
  short b;
  char ch2;
  int num;
};是12个字节
struct node
{
  short b;
  char ch1;
  char ch2;
  int num;
};是8个字节
#pragma pack(4) 4个字节对齐
#pragma pack() 恢复默认


2.struct数组


struct Student
{
  int num;
  char name[20];
  int age;
}
typedef struct Student Stu;
int main
{
  Stu AStu[3] = {
  {
    .num = 1,.name = "zhangsan",.age = 12
  },
  {
    .num = 2,.name = "lisi",.age = 13
  },
  {
    .num = 3,.name = "wangwu",.age = 14
  }
  };
  for(int i = 0; i < sizeof(AStu) / sizeof(Stu); i++)
  {
  printf("num = %d, name = %s , age = %d\n",AStu[i].num,AStu[i].name,AStu[i].age);
  }
}


3.柔性数组


struct node
{
  int len;
  int src[0];
};
typedef struct node Array;
int main()
{
  printf("sizeof(node) = %d\n",sizeof(struct node));
  Array a;
  a.len = 100;
  a.src = (char *)malloc(sizeof(char) * 100);
  a.src = (char *)realloc(sizeof(char) * 原有字节长度);
}


4.作业???


封装函数


二、union共用体


union定义类型,定义变量和指针、初始化

struct VS union:大小

union大小:保存的成员中最大字节长度的成员所决定:(保持字对齐)

存储方式:所有成员公用一段内存空间(最长字节数的变量)(数据覆盖)


CPU属性:大端字节序、小端字节序

利用共用体判断CPU的大小端字节序

0a2653c851af460fa595bd959398a8f1.png2d65d23f6d4748949b924e4057485923.png

多选一

0a2653c851af460fa595bd959398a8f1.png


三、enum枚举


enum:定义一系列整数宏

枚举变量 == 整型变量

enum VS #define

enum:定义一些列整数宏更加便捷,在编译阶段

#define :预处理,不安全,做傻瓜式替换
enum Result
{
  OK,
  NO,
  SUCCESS,
  FAILED
};
#define OK 0
#define NO 1
#define SUCCESS 2
#define FAILED 3
相关文章
|
网络协议 算法 Linux
【嵌入式软件工程师面经】Linux网络编程Socket
【嵌入式软件工程师面经】Linux网络编程Socket
760 1
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
926 15
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
794 13
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
1226 3
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
318 4
|
消息中间件 安全 Java
【嵌入式软件工程师面经】Linux多进程与多线程
【嵌入式软件工程师面经】Linux多进程与多线程
431 1
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
967 0
|
10月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
1020 1
二、Linux文本处理与文件操作核心命令
|
10月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
645 137
|
10月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1594 58