C语言结构体,结构体数组,结构体指针,伸缩型结构体成员,结构体和函数

目录

一,结构体

1,结构体变量

2,声明结构体变量与成员访问

2.1声明结构体变量

2.2成员访问 

3,结构体初始化

1.1常见初始化方式

1.2结构的初始化器

二,结构体数组

1,定义结构体数组

 2,标识结构体数组成员

三,结构体指针

1,声明结构体指针

2,初始化结构体指针

3,结构体指针访问成员

3.1方法一 

 3.2方法二

四,结构体和函数

1,传递结构体成员

 2,传递结构体

3,传递结构的地址

五,伸缩型数组成员


一,结构体

结构体是一些值得集合,这些值被称为成员变量,结构体成员得类型可以是任意一种C得数据类型,甚至还可以是别的结构体。

1,结构体变量

struct Stu{
 char name[20];
 int age ;
 char id[20];
};

struct,是结构体关键字,其之后的Stu是自定义得结构体变量;{}之间的是成员变量,} 之后的 :分号是声明所需要的,表示结构体布局定义结束。

结构体成员是结构体(结构体嵌套结构体)的例子:

struct stu{
 char name[20];
 int age;
 char id[20];
};

struct cl_rom{
 struct stu s; //结构体嵌套结构体
 char job[20];
 int quan;
};

2,声明结构体变量与成员访问

2.1声明结构体变量

定义结构体之后,我们可以在主函数中声明结构体变量,如:

int main()
{
struct Stu s ;
//声明结构体变量 s ,之后使用struct Stu时 可以用s代替 使操作简单
}
//还可以使用这种方式声明

struct Stu{
 char name[20];
 int age;
 char id[20];
}s;  //在分号前面声明结构体变量

2.2成员访问 

使用点(.)访问结构体成员

struct Stu{
 char name[20];
 int age;
 char id[20];
}s;  

s.name ;//访问 结构体中的 char name[20] ;
s.age;  //
s.id;   //

 注意不可以使用类型名(Stu)对成员进行访问

3,结构体初始化

1.1常见初始化方式

通过代码来讲述结构体初始化方式:

//定义时直接初始化
struct stu
{
	char name[20] = {"李四"};
	int age = 18;
	char id[20] = {"00002"};
};

//用声明直接初始化
struct stu
{
	char name[20] ;
	int age ;
	char id[20] ;
}s;
int main()
{
  s = { "张三",20,"0001" }; 
  //也可以使用在主函数体中的声明初始化
  struct stu s = {"李四",18,"1234"}	
}

//在结构体}后声明时初始化
struct stu
{
    char name[20] ;
	int age ;
	char id[20] ;
}s = { "张三",20,"0001" };

1.2结构的初始化器

结构的初始化器使用 ‘.’ 点运算符 和成员名 标识特定的元素 ,这种方式可能有的编译器无法使用:

struct stu
{
  char name[20];
  int age;
  char id[20];
};

int main()
{
  //使用结构体初始化器
 struct stu s = {.id = "+10086",
                 .age = 18,
                 .name = "张三"
             //使用初始化器,可以按照任意位序
                } ;
}

使用初始化器时,特别要注意最后一次的赋值才是成员获得的实际值:

struct stu s = {.id = "+10086",
                 .age = 18,
                 .name = "张三",
                 18   //这里是对age的初始化
               };
//age的值最后变成 18 
//在结构体成员声明时,age紧跟在name之后,所以对name初始化完成之后便可以找到age
//这点与数组初始化器类似

二,结构体数组

一个存放的元素是结构体的数组,是一个数组。

1,定义结构体数组

struct stu
{
    char name[20];
    int age;
    char id[20];
};
//结构体数组
struct stu stu_arr[2];

stu :数组元素类型 ,数组的每个元素都是一个stu类型的结构

stu_arr :数组名

 2,标识结构体数组成员

可以看到结构体数组成员的标识中,数组下标在stu_arr数组名之后,不是成员之后。

stu_arr[0]是结构变量名,结构体变量名和成员名之间用点(.)链接。

总结几种表示方式:

struct stu
{
    char name[20];
    int age;
    char id[20];
};
struct stu stu_arr[2];

stu_arr ;      //一个stu结构体数组
stu_arr[1];    //一个元素类型是stu结构体的数组元素
stu_arr[1].id; //数组中stu_arr[1]的成员,一个char类型的数组
stu_arr[1].name[4]; //数组中stu_arr[1]元素中成员name 的第五个元素

三,结构体指针

1,声明结构体指针

声明结构体指针和声明其它类型的指针一样

struct stu * c ;
//首先是结构体关键字 struct
//结构体类型 stu 
// * 表示c是指针

2,初始化结构体指针

struct stu
{
    char name[20];
    int age;
    char id[20];
};
struct stu stu_arr[2];

struct stu * s ;//声明结构体指针
s = &stu ; //初始化

当我们对结构体指针初始化为数组的一个元素时:

struct stu stu_arr[2];
struct stu *s = &stu_arr[0] ;
s = stu_arr ;
// 对指针+1时与数组类似,都是找到下一个元素的位置
//如s指向的是stu_arr[0],s+1指向的是stu_arr[1];

3,结构体指针访问成员

为了方便观看,在这里放置一个结构体和结构体指针,下述访问内容都可以在这里找到

struct stu {
	char name[20];
	int age;
	char id[20];
}s;
    struct stu arr[2];//结构体数组
	struct stu* p1; //结构体指针
    struct stu* p2;
	p1 = &s;        //结构体指针指向 stu这个结构体
    p2 = &arr[0];

3.1方法一 

使用 -> 运算符,是由一个连接号(-)和一个大于号(>)组成。

p1 == &s, 那么在引用结构体内容时 可以 : p1->name 就等价于 s.name;

p2 == &arr[0],  那么  : p2->name 就等价于 arr[0].name;

 3.2方法二

因为*(解引用)和 &(取地址)是一对互逆的运算符,所以可以写成下面的这个方式

(*p1).name  等价于  s.name

(*p2).name  等价于  arr[0].name

 先对指针进行解引用找到相对应的内容,再进行访问成员。

使用括号是因为,. 的优先级高于 * 的优先级。

访问成员的方式总结

  1. 使用点(.)运算符:结构名 . 成员名 ,s.name 
  2. 指针使用-> 访问 : p1->name
  3. 解引用指针然后访问成员: (*p1).name 

四,结构体和函数

传递参数的问题

struct stu {
	char name[20];
	int age;
	char id[20];
    int grades;
}s;
//第四段内容使用的结构体
//此结构体没有赋值,自己使用时需要赋值再操作

1,传递结构体成员

void my_print(int n, double b)
{
	printf("%d,%lf",n,b);
}
my_print(s.age, s.grades);
//通过.成员名访问,然后传递成员值
//这种传递不会修改成员变量的值

 2,传递结构体

void jiegou(struct stu name)//使用结构接受结构
{
	printf("%d\n",name.age);
}
jiegou(s); //传递结构
//传递过去的是一个副本,改变副本源不会受影响

 使用结构接受结构,编译器会以传递的结构为模板创建一个新的结构,新结构的值是被传递结构的值。

3,传递结构的地址

int dizhi(struct stu * p) //传递地址就需要对应的指针接收
{
 printf("%d ", p->name); //用指针访问成员
}
dizhi(&s); //传递地址

注意结构体变量名不是地址!!!

五,伸缩型数组成员

是结构体成员中最后一个数组成员具有的特性

  1. 该数组不会立即存在
  2. 使用这个伸缩型数组成员可以编写合适的代码,就像真实存在并具有具体大小的一样

声明一个伸缩型数组成员的规则

  1. 伸缩型数组成员必须是结构的最后一个成员
  2. 结构中必须至少有一个成员
  3. 伸缩型数组的声明类似于普通数组,知识方括号中的大小是空的

基于上述条件,建立一个伸缩型数组

struct stu
{
 char name[20]
 int age;
 int id ;
 int gread[];//伸缩型数组成员
}s;

声明的结构体变量s是不可以使用 伸缩型数组的,因为没有为这个数组分配空间,要使用时,用结构体指针接收malloc函数开辟的空间,malloc开辟的空间应该包括常规的数组成员和需要使用的gread所需要的额外空间。

struct stu *p ;
p = (struct stu*)malloc(sizeof(struct stu) + sizeof(int) * 5);
//用malloc开辟足够的空间
//然后通过指针去访问成员

p->name ;
p->gread[2];  //malloc时 为gread数组开辟了五个空间

使用伸缩型数组成员时应要注意:

  1. 不能用结构进行赋值或拷贝
  2. 不要以按值传递的方式把这种结构传递给结构
  3. 不要使用带伸缩型数组成员的结构作为另一个结构体的成员

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值