数据结构之结构体复习

为什么出现结构体?

  为了表示一些复杂的数据,一些基本数据类型无法满足要求,

当要用一个变量描述一个对象的多个属性时,普通的内置数据类型是表示不了的,这个时候就可以用结构体回。结构体和类很相似,唯一不同的是:结构体默认是公有成员,而类默认是私有成员。

什么叫结构体?C语言中的结构体

在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

结构体定义与声明

结构体的定义如下所示,struct为结构体关键字,tag为结构体的标志,member-list为结构体成员列表,其必须列出其所有成员;variable-list为此结构体声明的变量。 [1] 

 struct tag {member-list} variable-list ; 

在一般情况下,tag、member-list、variable-list这3部分至少要出现2个。以下为示例:

//此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//同时又声明了结构体变量s1
//这个结构体并没有标明其标签 
struct { int a; char b; double c; 
} s1;//同上声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//结构体的标签被命名为SIMPLE,没有声明变量
struct SIMPLE{ int a; char b;double c; 
};//用SIMPLE标签的结构体,另外声明了变量t1、t2、t3
struct SIMPLE t1, t2[20], *t3; 
//也可以用typedef创建新类型
typedef struct{int a;char b;double c; 
} Simple2;
//可以用Simple2作为类型声明新的结构体变量
Simple2 u1, u2[20], *u3;


注意事项:

在上面的声明中,第一个和第二声明被编译器当作两个完全不同的类型,即使他们的成员列表是一样的,如果令t3=&s1,则是非法的。 [1] 

结构体变量不能加减乘除,可以相互赋值

普通结构体变量和指针结构体变量作为函数传参数问题

#include <stdio.h>
#include <string.h>void f(struct Student *pst);
void g(struct Student std);
struct Student {int sid;char name[20];int age;char like[60];};  //此处分号不可省略int  main() {struct Student st;f(&st);   //传地址给结构体的属性赋值printf("%d  %s  %d  %s\n", st.sid, st.name, st.age, st.like);g(st);   //赋值之后,结构体变量的属性值验证while (true){}return 0;
}void f(struct Student *pst) {(*pst).sid = 99;strcpy_s(pst->name, "老王");pst->age = 18;strcpy_s(pst->like, "老王喜欢隔壁住富婆");
}void g(struct Student std) {printf("%d  %s  %d  %s\n", std.sid, std.name, std.age, std.like);
}

都能输出结果 

结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。

//此结构体的声明包含了其他的结构体
struct COMPLEX{char string[100];struct SIMPLE a;
}; 
//此结构体的声明包含了指向自己类型的指针
struct NODE{char string[100];struct NODE *next_node;
};

如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明,如下所示: 

struct B;    
//对结构体B进行不完整声明 
//结构体A中包含指向结构体B的指针
struct A{struct B *partner;//other members;
}; 
//结构体B中包含指向结构体A的指针,在A声明完后,B也随之进行声明
struct B{struct A *partner;//other members;
};

结构体作用:

结构体和其他类型基础数据类型一样,例如int类型、char类型,只不过结构体可以做成你想要的数据类型。以方便日后的使用。 [1] 

在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型。由于C语言内部程序比较简单,研发人员通常使用结构体创造新的“属性”,其目的是简化运算。 [1] 

结构体在函数中的作用不是简便,其最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了。 [1] 

结构体的大小与内存对齐

结构体的大小不是结构体元素单纯相加就行的,因为我们主流的计算机使用的都是32bit字长的CPU,对这类型的CPU取4个字节的数要比取一个字节要高效,也更方便。所以在结构体中每个成员的首地址都是4的整数倍的话,取数据元素时就会相对更高效,这就是内存对齐的由来。每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。 [1] 

规则:

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。 [1] 

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。 [1] 

3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

 

C++中的结构体

在C语言中,可以定义结构体类型,将多个相关的变量包装成为一个整体使用。在结构体中的变量,可以是相同、部分相同,或完全不同的数据类型。在C语言中,结构体不能包含函数。在面向对象的程序设计中,对象具有状态(属性)和行为,状态保存在成员变量中,行为通过成员方法(函数)来实现。C语言中的结构体只能描述一个对象的状态,不能描述一个对象的行为。在C++中,考虑到C语言到C++语言过渡的连续性,对结构体进行了扩展,C++的结构体可以包含函数,这样,C++的结构体也具有类的功能,与class不同的是,结构体包含的函数默认为public,而不是private。

C++控制台输出例子:

#include<cstdlib>
#include<iostream>
//定义结构体
struct point{//包含两个变量成员int x;int y;
};
using namespace std;
int main(int argc,char * argv[]){point pt;//加上struct的结构体变量定义是C语言的特征,而C++语言不需要这样pt.x=1;pt.y=2;cout<<pt.x<<endl<<pt.y<<endl;return EXIT_SUCCESS;
}

C++中的结构体与类的区别

类与结构体在C++中有三点区别。 [1] 

(1)class中默认的成员访问权限是private的,而struct中则是public的。

(2)从class继承默认是private继承,而从struct继承默认是public继承。

(3)C++的结构体声明不必有struct关键字,而C语言的结构体声明必须带有关键字(使用typedef别名定义除外)。

 

如何使用结构体?两种方式

struct Student st = {1000,"zhangsan",20};
struct Student *std = &st;1,st.sid = 500;2,std->sid=222; 

结构体使用代码: 

#include <stdio.h>
#include <string.h>struct Student {int sid;char name[20];int age;} st;  //此处分号不可省略int main(void) {//第一种方式struct Student st = {1000,"zhangsan",20};printf("%d  %s  %d\n", st.sid, st.name, st.age);st.sid = 500;// st.name="lisi"  //errorstrcpy_s(st.name,"lisi");st.age=20;printf("%d  %s  %d\n", st.sid, st.name, st.age);//第二种方式struct Student *std;std = &st;std->sid=222;  //std->sid   等价于  (*std).sid   所以等价 st.sidprintf("%d  %s  %d\n", st.sid, st.name, st.age);while(true){}}

 

结构体简单使用案例效果:

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

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

相关文章

高效管理读书笔记

高效管理读书笔记一、优秀的权威宣言二、主要的内容要点2.1 有权威的领导都会关心自己的员工2.2 问责而不指责2.3 多点尤达&#xff0c;少点超人三、原书一、优秀的权威宣言 优秀的权威就是&#xff1a; 指出大部分人视而不见的问题的气质今天畅所欲言而不是空等明天的好心【…

蒙特卡罗方法介绍(一)

蒙特卡罗方法介绍(一) 一、蒙特卡罗方法的基本思想和解题步骤 1.1 蒙特卡罗方法的基本思想 蒙特卡罗方法也称随机模拟法、随机抽样技术或统计实验发&#xff0c;其基本思想是&#xff1a;为了求解数学、物理、工程技术或生产管理等方面的问题。首先&#xff0c;建立一个与求…

神策数据张涛:如何让用户标签价值落地?

本文根据神策数据副总裁张涛在《用户个性化运营—标签体系搭建新机遇》主题沙龙中演讲整理所得。 标签系统&#xff0c;在企业中已不是什么“高大上”的说辞。然而让用户标签价值真正落地企业不多&#xff0c;就像“青少年谈性”&#xff0c; 有一段话形容得再贴切不过&#xf…

蒙特卡罗方法介绍( 二)

蒙特卡罗方法介绍( 二) 一、蒙特卡罗求解定积分 蒙特卡洛方法求解定积分有两种方法&#xff0c;一种是上一节中讲的投点法&#xff0c;另外一种是期望法&#xff08;也称平均值法&#xff09;。 1.1 投点法 给出如下曲线f(x)f(x)f(x),求f(x)f(x)f(x)在a,ba,ba,b上的积分&am…

大数据技术之kafka (第 3 章 Kafka 架构深入) 分区策略在分析

如果不懂分区策略请看我之前的文章&#xff1a;https://blog.csdn.net/ywl470812087/article/details/105328015 默认的方式我们采用的是Range策略方式&#xff08;按主题给消费者消费&#xff0c;主题被谁订阅了就谁消费&#xff09; 先看下下面这个图&#xff0c;画的很丑&a…

如何达成目标笔记

如何达成目标 一、本书主要内容 推荐序一 升级你的行动工具箱 推荐序二 人们可以改变 引言 成功者和自制力的悖论 //004 自制力到底是怎样的 //007 你能做什么 //009 本书的主题 //011 1.1 准备就绪 第1章 你明白自己去往哪里吗 别说“做到最好” //017 大局与细节 //…

大数据技术之 Kafka (第 4 章 Kafka API ) Producer API

4.1.1 消息发送流程 Kafka 的 Producer 发送消息采用的是异步发送的方式。在消息发送的过程中&#xff0c;涉及到了两个线程——main 线程和 Sender 线程&#xff0c;以及一个线程共享变量——RecordAccumulator。main 线程将消息发送给 RecordAccumulator&#xff0c;Sender…

《关键对话——何谓关键对话》读书笔记(一)

《关键对话——何谓关键对话》读书笔记&#xff08;一&#xff09; 利用假期的时间&#xff0c;将关键对话阅读了一遍&#xff0c;书中提到的观点&#xff0c;方法&#xff0c;场景等很适合我目前处的状态&#xff0c;有的时候读起来仿佛就是自己身临其境&#xff0c;有种感同身…

从java读取Excel继续说大道至简 .

在上一篇博客《从复杂到简单&#xff0c;大道至简》中说道我们要把复杂的问题简单化&#xff0c;也就是要把问题细分&#xff0c;让大问题变成小问题&#xff0c;这样解决起来会相对容易&#xff0c;当我们把容易的小问题解决掉了&#xff0c;大问题自动就会迎刃而解。 所以今天…

推荐算法工程师的成长之道

推荐算法工程师的成长之道 原创&#xff1a; gongyouliu 大数据与人工智能 3月20日 源链接&#xff1a;原文地址 本文&#xff0c;作者会基于自己的实践经验讲述推荐算法工程师的成长之道&#xff0c;这里的“道”有发展路径和道(道理、方法论、经验、智慧)两层意思。 所以本文…

java电子商务源码解读 b2b2c o2o

大型企业分布式互联网电子商务平台&#xff0c;推出PC微信APP云服务的云商平台系统&#xff0c;其中包括B2B、B2C、C2C、O2O、新零售、直播电商等子平台。 分布式、微服务、云架构电子商务平台 java b2b2c o2o 技术解决方案 开发语言&#xff1a; java、j2ee 数据库&#x…

信息流推荐多样性

信息流推荐多样性 一、问题现状 信息流产品中一个常见的问题是多样性越来越差&#xff0c;造成这种问题的原因在于机器学习算法本身。下面通过一副系统循环图来介绍多样性差的问题。 资讯库随机推荐文章&#xff0c;由于是按照全库比例采样&#xff0c;娱乐占比较大&#xf…

Robocode教程2——你的第一个robo,取个好名字哦

摘自&#xff1a;http://site.douban.com/widget/notes/7736245/note/210029011/ 你需要准备的东西&#xff1a;1.c语言的知识和一点点的java知识&#xff0c;robocode意在学习java&#xff0c;不要要太深的java水平&#xff0c;你只要理解java和c的区别就可以了。2.robocode A…

UI设计师的面试过程

Palantir Technologies是一家提供分析、整合、可视化各种数据的IT型技术公司。在该公司&#xff0c;前端工程师和后端工程师有同样的面试过程&#xff0c;前端工程师也需要的一定的编程基础。该公司技术博客Palantir TeckBlog日前发表了一篇博文《The UI Design Interview》&am…

数据在市场运营中的应用

数据在市场运营中的应用 1. 背景 目前的产品运营、用户拉新、渠道投放、留存等都是靠人工进行策略制定&#xff0c;有的公司和部门完全靠着以前的经验在尝试互联网产品的市场营销和运营。这样不仅效率很低&#xff0c;而且效果也不显著。 主要存在的问题有以下几点&#xff…

信息流项目计划和思路

目录 一、对项目的认识. 4 1&#xff0e;用户需求和竞品. 4 2. 项目现状. 4 3. 发展前景. 4 二、项目的业务方向和思路. 6 1. 业务方向. 6 2. 2020年目标. 6 3. 思路. 6 3.1用户留存提升&#xff08;6%->12%&#xff09;. 6 3.2日活提升&#xff08;30万->80万…

MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结

MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中&#xff0c;N指的是字符的长度,VARCHAR类型最大支持65535,指的是65535个字节,但并不支持65535长度的varchar&#xff0c;65535中应该包含了所有字段的长度、变长字段长度标示…

链表的分类

分类: 单链表 双链表:每一个节点有两个指针域 循环链表&#xff1a;能通过任何一个节点找到其他所有的结点 非循环链表 链表中第一个结点的存储位置叫做头指针&#xff0c;那么整个链表的存取就必须是从头指针开始进行了。之后的每一个结点&#xff0c;其实就是上一个的后继指…

机器学习基础笔记总结

最近在学习latex&#xff0c;将之前的机器学习基础知识相关的笔记用latex整理了以下&#xff0c;源地址如下&#xff1a; https://github.com/duankai/latex_book&#xff0c;感兴趣的可以自由下载&#xff0c;也可以随意使用latex的格式。 pdf 效果如下&#xff0c;文件可在h…