首页 > 其他分享 >C语言结构体

C语言结构体

时间:2024-09-21 18:25:02浏览次数:13  
标签:struct int C语言 char printf 对齐 结构

目录

结构体

含义解释

结构的声明

结构体变量的创建和初始化

结构的特殊声明

结构的自引用

结构体内存对齐

对齐规则

例子示范

为什么存在内存对齐

1. 平台原因 :

2. 性能原因:

3. 总体来说:

修改默认对齐数 

结构体传参 


结构体

含义解释

1. 结构是⼀些值的集合,这些值称为成员变量。

2. 结构的每个成员可以是不同类型的变量。

结构的声明

struct tag
{
    member-list;
}variable-list;
struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
}; //分号不能丢

结构体变量的创建和初始化

#include <stdio.h>
struct Stu
{
 char name[20];//名字
 int age;//年龄
 char sex[5];//性别
 char id[20];//学号
};
int main()
{
 //按照结构体成员的顺序初始化
 struct Stu s1 = { "张三", 20, "男", "20230818001" };
 printf("name: %s\n", s1.name);
 printf("age : %d\n", s1.age);
 printf("sex : %s\n", s1.sex);
 printf("id : %s\n", s1.id);
 
 //按照指定的顺序初始化
 struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = 
"⼥" };
 printf("name: %s\n", s2.name);
 printf("age : %d\n", s2.age);
 printf("sex : %s\n", s2.sex);
 printf("id : %s\n", s2.id);
 return 0;
}

结构的特殊声明

1. 在声明结构的时候,可以不完全的声明。

2. 匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。

//匿名结构体类型
struct
{
    int a;
    char b;
    float c;
}x;//只能在后面接着创建变量

结构的自引用

1. 结构体不能直接引用该类型自身。

2. 但可以存放该类型的指针。

 struct Node
{
    int data;
    struct Node* next;//正确
    struct Node next;//错误
};

结构体内存对齐

对齐规则

1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处

2. 其他成员变量要对齐到某个数字(对⻬数)的整数倍的地址处。(对齐数 = 编译器默认的⼀个对齐数与该成员变量大小的较小值。)

3. 结构体总大小为最大对齐数的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到⾃⼰的成员中最⼤对齐数的整数倍处,结构 体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对⻬数)的整数倍。

例子示范

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	struct S1
	{
		char c1;//0 (1 2 3)
		int i;//4 5 6 7
		char c2;//8
		//目前一共9个字节,自动变成12
	};
	printf("%d\n", sizeof(struct S1));
	return 0;
}

struct S2
{
	char c1;//0
	char c2;//1
	int i;//4 5 6 7
	//目前一共8个字节,成立
};
printf("%d\n", sizeof(struct S2));

struct S3
{
	double d;//0 ... 7
	char c;//8
	int i;//12 13 14 15 
	//目前一共16个字节,成立
};
printf("%d\n", sizeof(struct S3));

为什么存在内存对齐

1. 平台原因 :

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定 类型的数据,否则抛出硬件异常。

2. 性能原因:

数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数,那么就可以⽤⼀个内存操作来读或者写值了。否则,我们可能需要执⾏两次内存访问,因为对象可能被分放在两个8字节内存块中。

3. 总体来说:

结构体的内存对⻬是拿空间来换取时间的做法。

修改默认对齐数 

1. 结构体在对齐方式不合适的时候,我们可以自己更改默认对⻬数。

2. #pragma 这个预处理指令,可以改变编译器的默认对⻬数。(Vs默认8)

#include <stdio.h>
#pragma pack(1)//设置默认对⻬数为1
struct S
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的对⻬数,还原为默认
int main()
{
 //输出的结果是什么?
 printf("%d\n", sizeof(struct S));
 return 0;
}

结构体传参 

1. 结构体的定义最好在main()函数之前。

2. 注意结构体如果是局部变量,就存在适用范围的限制。、

3. 结构体传参,可以把那个结构体变量整个传过去。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void print1(struct S s);
struct S
{
	int data[1000];
	int num;
}s = { {1,2,3,4}, 1000 };;//一定要在main外卖声明结构体变量
int main()
{
	print1(s);
	return 0;
}
void print1(struct S s)//结构体传参
{
	printf("%d\n", s.num);
}

标签:struct,int,C语言,char,printf,对齐,结构
From: https://blog.csdn.net/hsy1603914691/article/details/142288412

相关文章

  • 数据结构和算法——基本思想
    一.分治法分治法思想:将原问题分成n个规模较小的而结构与原问题相似的子问题,递归地解这些问题,然后合并其结果就得到原问题的解。分解:原问题分为若干个子问题,这些子问题是原问题的规模较小的实例。解决:递归地求解各个子问题。若子问题足够小,则直接求解。合并:将子问题的解合并成......
  • 理解C语言之深入理解指针(一)上
    目录1.内存和地址1.1内存1.2究竟该如何理解编址2.指针变量和地址2.1取地址操作符(&)2.2指针变量和解引⽤操作符(*)2.2.1指针变量2.2.2如何拆解指针类型2.2.3解引⽤操作符2.3指针变量的⼤⼩3.指针变量类型的意义3.1指针的解引⽤3.2指针+-整数3.3void*......
  • 理解C语言之深入理解指针(一)下
    目录5.指针运算5.1指针+-整数5.2指针-指针5.3指针的关系运算6.野指针6.1野指针成因6.2如何规避野指针6.2.1指针初始化6.2.2⼩⼼指针越界6.2.3指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性6.2.4避免返回局部变量的地址7.assert断⾔8.指针......
  • 【C语言】⾃定义类型:联合和枚举
    ⾃定义类型:联合和枚举1.联合体1.1联合体类型的声明1.2联合体的特点1.3相同成员的结构体和联合体对⽐1.4联合体⼤⼩的计算1.5联合的⼀个练习2.枚举类型2.1枚举类型的声明2.2枚举类型的优点2.3枚举类型的使⽤1.联合体1.1联合体类型的声明像结构体⼀样,联......
  • C语言指针详解与应用
    C语言指针1.指针简介指针与底层硬件紧密联系,使用指针可操作数据地址,实现数据的间接访问2.计算机存储机制在C语言中内存的分配是以一个字节为单位进行线性分配且每个字节都会对应的地址inta=0x12345678;shortb=0x5A6B;charc[]={0x33,0x34,0x35};**int......
  • PHP数组转树形结构,获取任意子节点的全部父节点
    /***递归无限级分类,获取任意节点下所有子孩子*@paramarray$arr*@paramint|string$pid父级节点*@paramstring$p_name父级节点名称*@paramint$level层级数*@returnarray*/functionget_tree_all_children(array$arr,int|string$pid=0,strin......
  • Redis:内存数据结构存储终极指南
    redis是不断发展的数据管理和存储领域中广泛使用的技术。redis被公认为内存中数据结构存储,它提供了广泛的功能,使其成为从缓存到实时分析等各种应用程序的标准基础。这个综合教程将介绍redis是什么、它的核心功能、用例以及如何开始。什么是redis?redis代表远程字典服务......
  • 初识数据结构和算法
    说在前面:⭐看到这篇文章的友友你好啊,在学习的路途中欢迎你的私信、留言,交流互动啊,我们一起学习、一起进步呀!⭐目录数据和结构解释含义数据的属性划分数据和算法的关系算法中复杂度时间复杂度空间复杂度数据和结构解释含义......
  • 帝国CMS栏目数据库表的结构与功能 (帝国cms栏目数据库表)
    帝国CMS中栏目信息通常存储在一个名为 phome_enewsclass 的表中(如果使用了默认的表前缀 phome_)。表的具体结构可能会根据帝国CMS的不同版本有所变化,但基本字段通常是相似的。主要字段classid:栏目ID,通常为主键,标识每一个栏目。parentid:父栏目ID,表示该栏目属于哪一个上级栏目......
  • 如何批量导入多个表结构到MySQL数据库:方法与实践
    方法一:使用SQL脚本文件创建SQL脚本文件:创建一个或多个包含所有CREATETABLE语句的文本文件。例如,你可以有一个名为schema.sql的文件,里面包含了所有表的定义。--创建部门表CREATETABLEdepartments(dept_noCHAR(4)NOTNULL,dept_nameVARCHAR(40)NOTNULL,......