C语言基础(九)结构体_结构体变量各个成员之间存在缝隙_黑暗守护者的博客-程序员宅基地

技术标签: C语言基础  c++  c语言  

结构体(structure)

在C语言中,我们是用结构体来存放一组类型不一样的数据。例如一个模特有身高(int)、姓名(char)、性别(bool)等。这个时候就需要用到结构体了。

1.结构体的声明

struct  结构体名
{
    
	结构体成员变量1;
	结构体成员变量2;
	······
};

示例:

struct  person
{
    
	int height;			//身高
	char name[20];		//姓名
	char address[50];	//地址
	bool gender;		//性别,1为男,2为女
};

注意:大括号后面的分号(;)不能忘

结构体是程序员自己定义的数据类型,可以包含多个其他类型的数据,也可以包含其他结构体,也可以包含指向自己的结构体指针(通常指向下一个结构体)。而这种结构体指针是为了实现一些比较高级的数据结构,链表和树等。

2.结构体变量的定义

结构体是一种程序员自定义的数据类型,可以用它来定义变量,例如:

1.先声明后定义

struct  person
{
    
	int height;			//身高
	char name[20];		//姓名
	char address[50];	//地址
	bool gender;		//性别,1为男,2为女
};



struct person studet;
struct person teacher;
struct person doctor;

上述代码就定义了三种变量,学生student,老师teacher,医生doctor。

2.声明的时候定义

struct  person
{
    
	int height;			//身高
	char name[20];		//姓名
	char address[50];	//地址
	bool gender;		//性别,1为男,2为女
}student,teacher,doctor;

3.结构体占用内存的情况

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<stdbool.h>


struct  person
{
    
	int height;			//身高
	char name[20];		//姓名
	char address[50];	//地址
	bool gender;		//性别,1为男,2为女
};
/*
 *
 *
 */


int main()
{
    
	struct person 	student;
	struct person 	teacher;
	struct person 	doctor;

	printf("sizeof(person) is%d\n",sizeof(student));


}

运行结果:

sizeof(person) is76

因为bool类型在内存中占据1个字节。这说明结构体各个成员变量之间存在“缝隙”,并不是连续的存储在一片内存中的。C语言也提供了结构体成员之间内存对齐的方法,但是我们在这里就不过多介绍了,请读者自行查阅。

4.结构体初始化

采用memset函数进行初始化,对结构体变量的值清零。

memset(&student,0,sizeof(student));		//注意要是用取值地府,因为结构体变量名不能表示其地址。

5.成员变量的访问和使用

1.使用.来访问结构体中的成员变量

student.height=150;
scanf("%s",student.name);

struct person student;
struct person* p=&student;
(*p).height=182;		//(*p)前后的括号不能少
strcpy((*P).name,"zunnajim);

2.使用->来访问(只能指针)

struct person student;
struct person* p=&student;
p->height=180;
strcpy(p->name,"zunnajim');

6.结构体数组

结构体变量可以被定义为数组,本质上与其他类型的数组变量没什么区别。

struct person master[10];
memset(master,0,sizeof(master));
strcpy(master[0].name,"zunnajim");
master[0].height=170;

7.结构体指针

struct person student;
struct person* p=&student;
(*p).height=182;
strcpy((*P).name,"zunnajim);

8.结构体的复制

在C语言中,结构体的成员变量如果是基本数据类型(int,char,double)可以用=来赋值,如果是字符串,可以用strcpy函数来赋值。
如果把结构体变量的值赋给另一个结构体变量中,有两种办法。
1.逐个赋值
逐个赋值就是把一个结构体变量的成员一个一个赋给另一个结构体的成员变量中,这种方式比较复杂,而且耗时。
2.内存拷贝
另一种办法就是内存拷贝,C语言提供了memcpy(memory copy)函数来实现内存的拷贝。
函数声明:

void *memcpy(void *dest,const void *src,size_t n);
/*参数说明
*src:源内存变量的起始地址
*dest:目的内存变量的起始地址
*n:需要复制的字节数
*/

示例:

/*******************************************************
* Author       : ZUNNAJIM 
* Last modified: 2020-11-22 02:33
* Email        : [email protected]
* blog         : https://blog.csdn.net/weixin_45859425 
* Filename     : copy.c
* Description  : This file is for copy methods for structure;
* *****************************************************/

#include<stdlib.h>
#include<stdio.h>
#include<string.h>


struct person
{
    
	int age;
	double height;
	char name[20];
}student;

int main()
{
    
	memset(&student,1,sizeof(student));
	student.age=20;
	student.height=180;
	strcpy(student.name,"zunnajim");
	printf("sizeof(student)=%d\n\n",sizeof(student));


	struct person student2;
	memcpy(&student2,&student,sizeof(student));
	printf("student2.age=%d\n",student2.age);
	printf("student2.height=%lf\n",student2.height);
	printf("student2.name=%s\n",student2.name);
	
	printf("sizeof(student2)=%d\n\n",sizeof(student2));
}

运行结果:

sizeof(student)=40
student2.age=20
student2.height=180.000000
student2.name=zunnajim
sizeof(student2)=40

9.结构体作为函数的参数

结构体是多个变量的集合,作为函数的参数时就可以传递整个集合,也就是所有成员。如果结构体成员较多,影响程序的运行效率,所以最好的办法就是传递结构体的地址。
示例:

/*******************************************************
* Author       : ZUNNAJIM 
* Last modified: 2020-11-22 20:37
* Email        : [email protected]
* blog         : https://blog.csdn.net/weixin_45859425 
* Filename     : parameter.c
* Description  : 
* *****************************************************/


#include<stdlib.h>
#include<stdio.h>
#include<string.h>


struct person
{
    
	int age;
	double height;
	char name[20];
}student;

void set_value(struct person *ptr)
{
    
	ptr->age=20;
	ptr->height=180;
	strcpy(ptr->name,"zunnajim");
}

int main()
{
    
	memset(&student,0,sizeof(student));

	set_value(&student);

	printf("student.age=%d   student.height=%f   student.name=%s\n",student.age,student.height,student.name);

}

运行结果:

student.age=20 student.height=180.000000 student.name=zunnajim

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45859425/article/details/109913832

智能推荐

浅析 Fragment 回退栈_xk_一步一步来的博客-程序员宅基地

在我们使用 fragment 的时候 ,总是会使用到 fragmentTransaction 的 add remove 和 replace 方法, 这些方法对 fragment 生命周期有着不同的影响, 在来个 回退栈, 就更加容易混淆. 我们通过开启回退栈和关闭回退栈来分别查看 fragment 的生命周期来了解 fragment 回退栈对..._fragment 回退

struct stat结构体:获取指定路径的文件或者文件夹的信息_struct 获取文件夹大_Tobiu的博客-程序员宅基地

_stat函数用来获取指定路径的文件或者文件夹的信息。struct stat这个结构体是用来描述一个linux系统文件系统中的文件属性的结构。//需要包含的头文件 #include #include int stat(  const char *filename //文件或者文件夹的路径  , struct stat *buf //获取的信息保存在内存中); _struct 获取文件夹大

ASP.NET MVC+Redis (准备工作)_asp.net mvc redis_HoYu_Z的博客-程序员宅基地

今天准备更新这个项目的第二篇博客。有一点需要说明的是之前觉得用的是Asp.net的WebPage,经过查看微软的官方文档还有相关的博客,相比较而言使用起来需要安装一个自动工具WebMatrix可以很快的搭建页面,除此之外我认为使用和学习价值并不是很大,所以决定整个项目框架更换为Asp.netMvc。GitHub仓库创建在GitHub上创建一个自己的仓库,选择好开发工具,添加.gitignore和r_asp.net mvc redis

Linux命令常见面试题_linux命令面试题_是阳阳呀的博客-程序员宅基地

问题一:绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令?答案:绝对路径: 如/etc/init.d当前目录和上层目录: ./ …/主目录: ~/切换目录: cd问题二: 怎么查看当前进程?怎么执行退出?怎么查看当前路径?答案:查看当前进程: ps执行退出: exit查看当前路径: pwd问题三:怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户 id?查看指定帮助用什么命令?答案:清屏: clear退出当前命令: ._linux命令面试题

【Mac环境】安装psycopg2模块时报错收集_mac if you prefer to avoid building psycopg2 from _monkey-怡宝的博客-程序员宅基地

问题1:下载源码解压后使用python setup.py install返回错误:python setup.py installrunning installrunning bdist_eggrunning egg_infowriting psycopg2.egg-info/PKG-INFOwriting dependency_links to psycopg2.egg-info/..._mac if you prefer to avoid building psycopg2 from source, please install the

CocosCreator自动化绑定jsb__大猪的博客-程序员宅基地

与之前的cocos2dx js自定义js-binding不同,这次用的是Cocos2dx里的自动绑定技术,更加的简单、高效、规整以及方便得多。而且之前的手动写文件不能适应更新后的CocosCreator版本的情况。环境配置:JDK、NDK、SDK、ANT:这些环境变量,当打包成原生平台的时候,已经配置过。PYTHON:Mac自带有python,一般是python2.7。

随便推点

java unicode 乱码_java过滤乱码 \u形式乱码 unicode乱码_青州重楼上的博客-程序员宅基地

由于编辑人员从excel,word等乱七八糟的地方copy内容过来,其中有不可见的字符,导致输出内容看上去是对的,其实是多了一个零长度的字符(比如:\u2028,0000200B ZERO WIDTH SPACE),所以需要过滤掉不合法的unicode编码等特殊字符整理的正则:[\\u007f-\\u009f]|\\u00ad|[\\u0483-\\u0489]|[\\u0559-\\u055a]...

AsyncTask学习_digan5187的博客-程序员宅基地

记录下AsyncTask的学习心得: AsyncTask​类是用来处理异步请求的,当我们在UI线程(主线程)中执行耗时操作时(从网络获取数据,从数据库中获取数据,或者读取文件)会阻塞主线程的运行,导致界面不流畅,卡。这种情况下,我们需要将这些耗时的操作另起一个线程来执行,尽量在主线程中执行UI操作。 ​ 一般做法,我们用Thread+handler...

byte类型,一文就够了_FARO_Z的博客-程序员宅基地

byte类型解析因为byte类型在开发中使用得比较少,很多人都对其一知半解,我一开始也是,但是研究一下以后,对许多问题都能豁然开朗了。运算报错问题byte类型参数运算,无论是否超范围,都会报错:byte类型常数运算,超范围,会报错,不超范围,不会报错:这是因为:两个变量相加,先对类型进行提升,然后运算,再将运算结果赋值。两个常量相加,先计算常量数值,然后判断是否满足类型范围,再赋值。范围超出问题byte类型,范围是-128~127,但是如果相加结果超出范围,那显示的是什么结果?_byte类型

Python ElasticSearch一站式教程(基础操作篇)_python elasticsearch教程_飞Link的博客-程序员宅基地

一、安装库包名:elasticsearch下载命令普通版本:python -m pip install elasticsearch异步版本:python -m pip install elasticsearch[async]二、创建es对象Elasticsearch():实例化es对象host:IP地址port:端口号timeout:超时时间from elasticsearch import Elasticsearch# 实例化一个ip为localhost_python elasticsearch教程

pdo mysql num rows,PDO版本的mysql_num_rows($ result)== 0)_樱红蕉绿的博客-程序员宅基地

^ I believe it isn't the same question - The other authors code is different to mine, which needed a different answer. I successfully got my answer from this post and marked it as answered. Everything..._pdo $result->num_rows

ionic简单应用加列表_sui_yz的博客-程序员宅基地

var myapp=angular.module("modu",["ionic"]); myapp.controller("con",function($scope){ $scope.items=[1,2,3]; $scope.dorefresh=function(){ $scope.items.push($scope.items.length+1); $

推荐文章

热门文章

相关标签