C语言中的自定义类型:struct结构体

1.C语言中的结构体概述

C语言中的2种类型:原生类型(如intchar等)和自定义类型(structenum等)。结构体类型是是C语言中的用户自定义类型,主要功能是对功能相关的数据进行封装,它是一个或多个变量的集合,这些变量的类型可以不同。

例如一名学生可以由姓名和性别来描述,结构体中的成员也可以是一个结构体,例如名字由姓+名来描述。结构体由关键字struct来声明。

2.C语言中结构体的定义和使用

结构体使用时可以先定义好结构体类型,然后再用定义好的类型来定义变量。

结构体的几种定义方式:

  • 1.struct 结构体名{...};直接定义一个结构体
#include<stdio.h>

struct student	//定义结构体类型
{	
	char name[20];
	int age;
};

int main(int argc,char**argv)
{
	struct student a;//用定义好的结构体类型来定义变量
	a.age=20;//访问结构体成员
	printf("%d.\n",a.age);
	return 0;
}

  • 2.结构体也可以在定义结构体类型的同时定义结构体变量,下面这段代码就是在定义了一个struct student结构体类型的同时定义了一个struct student类型的变量stu
#include<stdio.h>

struct student
{	
	char name[20];
	int age;
}stu;//定义结构体类型的同时定义了一个struct student类型的变量stu

int main(int argc,char**argv)
{
	stu.age=20;//访问结构体成员
	printf("%d.\n",stu.age);
	return 0;
}

  • 3.也可以使用typedef来对结构体类型重命名,例如下面这段代码,但是此时{}后面跟着的stu是新的类型名,而不再是个变量:
#include<stdio.h>

typedef struct student
{	
	char name[20];
	int age;
}stu;//stu是新的类型名 而不是一个变量

int main(int argc,char**argv)
{
	stu a;
	a.age=20;
	printf("%d.\n",a.age);
	return 0;
}

3.从数组到结构体的进步之处

结构体可以认为是从数组发展而来的。其实数组和结构体都算是数据结构的范畴了,数组就是最简单的数据结构、结构体比数组更复杂一些,链表、哈希表之类的比结构体又复杂一些;二叉树、图等又更复杂一些。

但是数组有2个明显的缺陷:

  • 1.定义时必须明确给出大小,且这个大小在以后不能再更改。
  • 2.数组要求所有的元素的类型必须一致,更复杂的数据结构就致力于解决数组的这两个缺陷。

结构体就是用来解决数组的第二个缺陷的,可以将结构体理解为一个其中元素类型可以不相同的数组。结构体完全可以取代数组,只是在数组可用的范围内数组比结构体更简单。

4.结构体变量中的元素访问

数组中元素的访问方式表面上有2种:数组下标方式和指针方式,实质上这两种都是指针方式访问。

结构体变量中的元素访问方式也是一种,用 .或者 ->的方式来访问。当通过变量名来访问成员是就用变量名.成员名来访问;当通过指针来访问成员时,就用指针名->成员名来访问,举个栗子:

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

typedef struct student
{	//定义结构体类型
	char name[20];
	int age;
}stu;//stu是新的类型名 而不是一个变量

int main(int argc,char**argv)
{
	//通过变量名来访问成员是就用变量名.成员名来访问
	stu a;
	a.age=20;
	printf("%d.\n",a.age);

	//通过指针来访问成员时,就用指针名->成员名来访问
	stu* pa=(stu*)malloc(sizeof(stu));
	//C++可以用new
	//stu* pa=new stu;
	pa->age=30;
	printf("%d.\n",pa->age);
	return 0;
}

这里要注意的就是第17行,当定义一个结构体指针的时候还要手动申请一个该结构体的内存,然后把返回的指针给声明的结构体指针,才能用->正确引用。否则内存中只分配了指针的内存,没有分配结构体的内存,结构体实际上是不存在的。这时候用->引用会导致Segmentation fault (core dumped)

结构体的访问方式有点类似于数组下标的方式,结构体变量成员的 .或者 ->访问本质上也是用指针来访问的。

通过指针来访问结构体成员,指针加的值需要考虑到结构体内存对齐:

#include<stdio.h>

struct myStruct
{
	int a;
	double b;
	char c;
};

int main(int argc,char**argv)
{
	struct myStruct s1;
	s1.a = 12;
	s1.b = 5.5;
	s1.c = 'a';

	int*p1 = (int*)(&s1);
	printf("s1.a = %d.\n",*p1);
	
	double* p2 = (double*)(p1+2);
	printf("s1.b = %lf.\n",*p2);
	
	char*p3 = (char*)(p1+4);
	printf("s1.c = %c.\n",*p3);
	return 0;
}

输出:

s1.a = 12.
s1.b = 5.500000.
s1.c = a.
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值