C语言——结构体(全)

目录

一、结构体的设计

二、结构体变量的初始化

2.1结构体在内存表示;

2.2结构体初始化;

 2.3结构体指针变量

 2.4结构体嵌套结构体

三、结构体成员访问 

3.1、结构体成员访问

3.2、结构体变量和指针

​3.3、结构体和函数 

四、结构体与数组

五、计算结构体大小

三个规则:

例1、​

 例2、

指定对齐值

总结


一、结构体的设计

C语言提供了基本的数据结构,例如 char 、short 、int 、float....等类型;这些偶称为内置类型。怎样设计出来属于自己的类型?

程序员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称为结构体类型。

结构体的定义形式为

struct 结构体名
{成员列表(可以是基本的数据类型,指针,数组或其他结构类型)
};

举个例子来说吧;

客观事务(实体)是复杂的,要描述它必须从多方面进行;也就是用不同的数据类型来描述不同的方面;用学生实体来说:

学生拥有什么? 学号、姓名、性别、年龄;

struct Student
{char s_id[8];char s_name[8];char s_sex[4];int s_age;
};

注意以下几点;

(1)、关键字struct是数据类型说明符,指出下面说的是结构体类型;

(2)、标识符Student是结构体的类型名;

(3)、最后的分号一定要写;

二、结构体变量的初始化

结构体是一种数据类型,也就是说可以用它来定义变量。

结构体就像一个“模板”,定义出来的变量都具有相同的性质。可以将结构体比作“图纸”,结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的;

结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据、需要存储空间;

2.1结构体在内存表示;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

 C语言中  struct 不可少

2.2结构体初始化;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

 2.3结构体指针变量

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

 2.4结构体嵌套结构体

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

三、结构体成员访问 

3.1、结构体成员访问

结构体变量使用   .   访问;

结构体变量.对象

#include<stdio.h>
#include<string.h>
struct Date
{int year;int month;int day;
};
struct Student
{char s_name[20];struct Date birthday;float score;
};
int main()
{struct Student stu = { "liuwen",2000,10,1,99.9 };printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);stu.score = 77;printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);return 0;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

注意:对结构体变量整体赋值有三种情况

 (1)定义结构体变量(用{}初始化)

(2)用已定义的结构体变量初始化

(3)结构体类型相同的变量可以作为整体相互赋值;

在C语言中不存在结构体类型的强制转换。

3.2、结构体变量和指针

内置类型可以定义指针变量,结构体类型也可以定义结构体类型指针;

结构体类型指针访问成员的获取和赋值形式:

(1)(*p). 成员名(.的优先级高于*,(*p)两边括号不能少)

(2)   p->成员名(->指向符)

示例:

#include<stdio.h>
#include<string.h>
//#define _CRT_SECURE_NO_WARNINGS
struct Inventory//商品
{char description[20];//货物名int quantity;//库存数据
};
int main()
{struct Inventory sta = { "iphone",20 };struct Inventory* stp = &sta;char name[20] = { 0 };int num = 0;(*stp).quantity = 30;stp->quantity = 30;strcpy_s(name,sizeof(stp->description),stp->description);printf("%s %d\n", stp->description, stp->quantity);printf("%s %d\n", (*stp).description, (*stp).quantity);return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_15,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16 3.3、结构体和函数 

示例:

#include<stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
struct School
{char s_name[20];//学校int s_age;
};
void Print_a(struct School sx)
{printf("%s %d\n", sx.s_name, sx.s_age);
}
void Print_c(struct School* sp)
{printf("%s %d\n", sp->s_name, sp->s_age);
}
int main()
{struct School sx = { "xi'an",100 };Print_a(sx);Print_c(&sx);return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_13,color_FFFFFF,t_70,g_se,x_16

 内存什么的看上面;

两种传参那个更好?通过内存可以看出来;

四、结构体与数组

结构体数组,是指数组中的每一个元素都是一个结构体类型。在实际应用中,C语言结构体数组常被用来表示有相同的数据结构的群体,比如一个班的学生,一个公司的员工等;

例如:

#include<stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
struct Student
{char s_name[20];//姓名int age;//年龄float score;//成绩
};
int main()
{struct Student cla[] ={{"liuwen",18,149.9},{"qnge",18,145},{"anan",19,188},};return 0;
}

五、计算结构体大小

三个规则:

(1)、结构体变量的首地址,必须是结构体变量的“最大基本数据类型成员所占字节数”的整数倍;

(2)结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍;

(3)、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节”的整数倍;

示例:假设总零地址开始(计算)

例1、

struct node
{char cha;int ia;char chb;
};
int main()
{int size = 0;struct node sd = { 'a',2,'b' };printf("%d\n", sizeof(struct node));//12return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_12,color_FFFFFF,t_70,g_se,x_16

 例2、

struct node
{char cha;char chb;int ia;
};
int main()
{int size = 0;struct node sd = { 'a','b',2 };printf("%d\n", sizeof(struct node));//12return 0;
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5bCP5ZyG6IS4,size_12,color_FFFFFF,t_70,g_se,x_16

为什么要理解字节对齐问题?

(1)内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问变量,但是实际上, cup并非逐字节读写内存,而是以2,4,或8的倍数的字节块来读写内存,因此就会对基本数据类型的地址作出一些限制, 即它的地址必须是2, 4或8的倍数。那么就要求各种数据类型按照一定的规则在空间. 上排列,这就是对齐。

(2)有些平台每次读都是从偶地址开始,如果一个int 型(假设为32位系统)如果存放在偶地址开始的地方那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。

(3)由于不同平台对齐方式可能不同,如此一来,同样的结构在不同的平台其大小可能不同,在无意识的情况下,互相发送的数据可能出现错乱,甚至引|发严重的问题。

指定对齐值

预处理指令# pragma pack(n)可以改变默认对齐数。n取值是1,2, 4,8, 16。

总结

1)结构体变量的首地址,必须是MIN{"结构体最大基本数据类型成员所占字节数",指定对齐方式}大小的整数倍。
2)结构体每个成员相对于结构体首地址的偏移量,都是MIN{基本数据类型成员,指定对齐方式}大小的整数倍。
3)结构体的总大小,为MIN{结构体“最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式} 大小的整数倍。
 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/212287.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汇编-PROC定义子过程(函数)

过程定义 过程用PROC和ENDP伪指令来声明&#xff0c; 并且必须为其分配一个名字(有效的标识符) 。目前为止&#xff0c; 我们所有编写的程序都包含了一个main过程&#xff0c; 例如&#xff1a; 当要创建的过程不是程序的启动过程时&#xff0c; 就用RET指令来结束它。RET强制…

好细的Vue安装与配置

一、下载和安装Vue 官网下载地址Download | Node.js 选择适合自己的版本&#xff0c;推荐LTS&#xff0c;长久稳定版本。 我这里选择的是Windows Installer(.msi) 64-bit 下载好后&#xff0c;双击下载的安装包。 点next 勾选I accept............&#xff0c;点next 这里建…

MATLAB - text的两种使用方法

text小技巧 1. 常规使用&#xff08;Method 1&#xff09;2. 在显示画面的相对位置&#xff08;Method 2&#xff09;3. 举个例子 1. 常规使用&#xff08;Method 1&#xff09; text(x,y,txt)2. 在显示画面的相对位置&#xff08;Method 2&#xff09; text(string,‘ABC’,…

使用端口扫描工具解决开放端口威胁并增强安全性

从暴露网络漏洞到成为入侵者的通道&#xff0c;开放端口可能会带来多种风险向量&#xff0c;威胁到网络的机密性、完整性和可用性。因此&#xff0c;最佳做法是关闭打开的端口&#xff0c;为了应对开放端口带来的风险&#xff0c;网络管理员依靠端口扫描工具来识别、检查、分析…

跨境电商必须要海外代理IP吗?盘点五大海外代理IP

相信跨境电商人近日都为了2023的跨境黑五旺季奋战&#xff0c;而2024也即将来临&#xff0c;对于跨境人的考验一波接着一波&#xff0c;根据Adobe Analytics的数据&#xff0c;2022年黑色星期五的销售额创下91.2亿美元新高&#xff0c;网络星期的销售额同样达到创纪录的113亿美…

jenkins 参数构建

应用保存 [rootjenkins-node1 .ssh]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved i…

ubuntu搭建phpmyadmin+wordpress

Ubuntu搭建phpmyadmin wordpress Linux系统设置&#xff1a;Ubuntu 22配置apache2搭建phpmyadmin配置Nginx环境&#xff0c;搭建wordpress Linux系统设置&#xff1a;Ubuntu 22 配置apache2 安装apache2 sudo apt -y install apache2设置端口号为8080 sudo vim /etc/apache…

Java中23种设计模式

一、创建型模式 1.单例模式&#xff08;Singleton Pattern&#xff09; 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建。这个类提…

leetcode刷题之用栈实现队列(C语言版)

leetcode刷题之用栈实现队列&#xff08;C语言版&#xff09; 一、题目描述二、题目要求三、题目解析Ⅰ、typedef structⅡ、MyQueue* myQueueCreateⅢ、void myQueuePush(MyQueue* obj, int x)Ⅳ、int myQueuePeek(MyQueue* obj)Ⅴ、int myQueuePop(MyQueue* obj)Ⅶ、bool myQ…

微服务保护 Sentinel

1.初识Sentinel 文章目录 1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结 1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel 1.4.微服务整合Sentinel 2.流量控制2.1.簇点链…

【Vue】创建第一个实例

步骤&#xff1a; 1.创建容器 2.引包 3.创建实例 4.添加配置项 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!--准备容器 --> <di…

轻松搞定HTTP接口测试,JMeter让你事半功倍!

jmeter-http接口测试脚本 jmeter进行http接口测试的主要步骤&#xff08;1.添加线程组 2.添加http请求 3.在http请求中写入接口的URL&#xff0c;路径&#xff0c;请求方式&#xff0c;参数 4.添加查看结果树 5.调用接口&#xff0c;查看返回值&#xff09; 针对接口添加heade…