结构体语法梳理1-基本定义及使用

一、为什么用结构体 

C语言中的基本数据类型,用来描述现实生活中的一些事物,比如:一个学生有年龄、学号等属性,我们分别用 int 变量存储年龄、学号,那么我们会写出以下代码:

int age;

int num;

如果 我们想存储多个学生的信息那么有以下两种写法:

A 定义多个变量:

int  age1,age2,age3;

int  num1,num2,num3;

B 定义数组:

int age[10];

int num[10];    

但是注意:年龄和学号之间是有联系的,他们都是某个学生的属性,以上代码在他们之间的联系上体现的不足:

比如 age1 与 num1 表示的是同一个学生还是 age1与num2表示的是同一个学生?

我们需要的是把学生看做一个整体在代码里表示,而不是把他的属性分散来看,C语言里用结构体这种组合类型来解决这个问题,关键字struct 。

二、结构体基本定义及使用

2.1 结构体定义

struct 结构体名{

      类型  成员名;

      类型  成员名;

      .......

 };

如果要创建一种类型要描述学生的信息,如编号,年龄,姓名,可以如下定义:

struct stu{
  int num;//成员
  int age;//成员
  char name[10];//成员
};

2.2 结构体变量定义

struct stu 是数据类型(注意不是stu),c语言里定义变量的基本模型是:

数据类型  变量名;

int  a;

所以定义 一个学生变量用如下方法:

struct stu  stu1;
struct stu  stu2,stu3;

stu1,stu2,stu3 是变量,变量的定义伴随这内存的分配,这时候会在内存中申请 sizeof(struct stu)个字节用来存储信息。

也可以在定义结构体的时候直接定义变量:(一般不这么使用)

struct stu{
  int num;
  int age;
    char name[10];
}stu1,stu2;

注意这里每次定义变量的时候都要写struct 关键字,比较麻烦,我们可以使用typedef 来为struct stu起一个别名

typedef 简单回顾:

typedef 为已知类型起一个别名

比如 

typedef  int myint;
这里 myint  a;等效于 int a;
typedef  unsigned int uint;
这里 uint  a;等效 unsigned int a;
对结构体typedef 

typedef struct stu   s_stu;
typedef struct stu*  p_stu;
s_stu  stu1;//等效于struct stu stu1;
p_stu  p1;//等效于struct stu *p1;

也可以在定义结构体的时候直接typedef 

typedef struct stu{
  int age;
  int num;
    char name[10];
}s_stu,*p_stu;
甚至可以省略 struct 后面的stu

typedef struct{
  int age;
  int num;
    char name[10];
}s_stu,*p_stu;

疑问1:

大家可以验证一下sizeof(struct stu)是多少, 貌似不是4+4+10 = 18 ,这里暂且放下,后面再讨论。

2.3 结构体变量访问及初始化

结构体成员的访问有两种方式  :
(1) 变量名.成员
(2) 地址->成员   //注意 -> 只是个操作符,跟 . 是等效的,不要把它理解成为指向的意思。
s_stu stu1;
p_stu p1;
p1 = &stu1; //p1存储stu1的地址
stu1.age = 1;
p1->num = 2;
(*p1).num = 3;//这里仅仅从语法层面上先理解   p1 = &stu1 ,  *p1 = stu1

在这里,结构体成员的访问就是这中类型的变量的基本访问,只不过在成员前面 加了 stu1. 或者 p->。

比如数组的访问只能一个一个元素访问

char name[10];
name[0] = 'a';
name[1] = 'b';
而不能 
name = {'a','b'};
放在结构体也同样使用,只不过前面放了 stu1. 或者  p->

stu1.name[0] = 'a';
stu2.name[1] = 'b';
p->name[2] = 'c';
p->name[3] = 'd';

获取成员的地址用以下方式 

&stu1.age;
&p1->age;

对于一维数组来说 数组名可以代表第一个元素的地址,因此有以下代码

strcpy(name,"lilei");

放在结构体里就是

strcpy(stu1.name,"lilei");

或者

strcpy(p->name,“lilei”);

(3)以下写一个综合例子来使用结构体

int main(int argc,char* argv[])
{
	//定义结构体变量要加上 struct 关键字。
	struct stu  stu1;
	s_stu  stu2;
	p_stu  p1,p2;
	/*
	结构体成员访问,结构体成员的使用跟单独使用一样,
	只不过是多了stu1.xx;而且必须加上前缀 stu1.用来
	标示是哪个结构体变量.
	*/
	p1 = &stu1;
	stu1.num = 1;
	stu1.age = 18;
	/*
	注意不要把这里写成 stu1.name = "stu1";
	name是个数组,数组的赋值只能一个一个元素赋值。
	*/
	strcpy(stu1.name,"stu1");
	//指针访问成员 用 ->
	p2 = &stu2;
	p2->num = 1;
	p2->age = 18;
	strcpy(p2->name,"stu2");
	
	printf("num = %d\n",p1->num);
	printf("age = %d\n",(*p1).age);
	printf("name = %s\n",p1->name);
	
	printf("num = %d\n",stu2.num);
	printf("age = %d\n",stu2.age);
	printf("name = %s\n",stu2.name);	
	return 0;
}

(4)结构体变量初始化

typedef struct stu{
  int num;
  int age;
    char name[10];
}s_stu,*p_stu;

 结构体变量初始化有以下两种方式:

 省略成员名,成员的值必须与成员的顺序一致,之间用逗号隔开,最后一个成员可以不写逗号。

struct stu stu1  =  {10,10,”stu1”};

初始化的时候可以只初始化前面的成员,而不初始化后面的成员,顺序不能变,后面的成员内存处全部为0。

/*
  num 为 10
  age 为 0
  Name[0]~name[9]为0
*/
struct stu stu2  =  {10,};
以下写法是不对的
struct stu stu3  =  { 10,“123123”,};

加上成员名,注意成员名前有个“.”,成员的值必须与成员的顺序可以不一致,也可以省略。


struct stu stu2  =  {
  .age = 2,
  .num = 2,
  /*注意这里是数组的初始化*/
  .name = “lilei”
};
struct stu stu3  =  {
  .age = 3,
  .name = “jim”,
  .num = 3
};

struct stu stu4  =  {
  .name = “tom”,
  .num = 3
};
以下写代码验证
int main()
{
	struct stu stu1 = {
			10,10,"stu1"
	};
	struct stu stu2 = {
			1,
	};
	struct stu  stu3 = {
			.num = 1,
			.name = "stu3",
			.age = 2
	};
	struct stu  stu4 = {
			.num = 1,
			.age = 2,
			.name = "stu4"
	};
	struct stu  stu5 = {
			.name = "stu5"
	};
	

	printf("num = %d\n",stu1.num);
	printf("age = %d\n",stu1.age);
	printf("name = %s\n",stu1.name);	
	printf("num = %d\n",stu2.num);
	printf("age = %d\n",stu2.age);
	printf("name = %s\n",stu2.name);
	printf("num = %d\n",stu3.num);
	printf("age = %d\n",stu3.age);
	printf("name = %s\n",stu3.name);
	printf("num = %d\n",stu4.num);
	printf("age = %d\n",stu4.age);
	printf("name = %s\n",stu4.name);
	printf("num = %d\n",stu5.num);
	printf("age = %d\n",stu5.age);
	printf("name = %s\n",stu5.name);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值