从“追求尽量不出错”,到正视“出错是必然|

如此而已~~~

园龄:3年3个月粉丝:0关注:12

C语言结构体

C语言结构体

引言:数组是可以存储多个“同一数据类型”变量集合,而结构体是定义一个新的数据类型,使其可以在这个新的数据类型存储“多个不同的数据类型。”

结构体的定义:

struct 结构体类型名//此处结构体类型名是指合法的字符串。(这里struct加上结构体类型名共同构成一个新的数据类型。)
{
int a;//这里面的我们称其为结构体成员。
float b;
double c;
char d;
};注意这里得到分号不要打漏

以上便是结构体的定义语法。

下面我们来看看如何使用:

首先提及一下typedef这个关键词。(作用是给数据类型取别名:typedef 原数据类型名 新数据类型名)

struct name
{
int a;
float b;
double c;
char d;
};
typedef struct name name;//这里是把新的数据类型名struct name改为name的意思。

然后我们就开始看看定义好的结构体数据类型如何使用。

#include <stdio.h>
struct name//结构体定义;
{
int a;
float b;
double c;
char d;
};
typedef struct name name;//结构体更改数据类型名。
int main()//这里需要引入“结构体变量”与结构体的点运算符“.”
{
name x1,x2={11,4.14,4.14159,'B'};
x1.a=10;
x1.b=3.14;
x1.c=3.14159;
x1.d='A';
printf("%d %f %lf %c\n",x1.a,x1.b,x1.c,x1.d);
printf("%d %f %lf %c\n",x2.a,x2.b,x2.c,x2.d);
return 0;
}

上面我们就提到了“定义结构体就是定义一个新的数据类型”,回忆之前面的内容我们可以回想起的有“int float double char”等数据类型,那么我们在主函数main里面通常是怎么进行使用的呢?答案是通过变量来实现。

所以结构体既然是一个数据类型也会通过变量来使用,这里结构体变量有x1与x2,其中变量x2在定义时就直接初始化了(对应相应的数据类型以“,”隔开来赋值),而x1则是一个一个对应初始化的,我们可以发现是通过“x1.a”(结构体变量.成员名)等形式来进行变量的寻找并赋值的。

这里再说一下结构体变量:

struct name
{
......;
......;
}变量名;

这样是可以在定义时直接将变量也定义好的语法,但因为想熟悉一下typedef关键词一下基本不使用。


接下来我们再来看看结构体的一些使用:

(1)结构体的镶嵌:

#include <stdio.h>
struct name1//镶嵌的结构体一定要在所镶嵌的结构体之前定义。
{
float b;
double c;
};
typedef struct name1 name1;
struct name2
{
int a;
name1 x;
char d;
};
typedef struct name2 name2;
int main()
{
name2 x1,x2={11,4.14,4.14159,'B'};
x1.a=10;
x1.x.b=3.14;//仍是通过变量名加“.”来进行寻找并赋值的。
x1.x.c=3.14159;
x1.d='A';
printf("%d %f %lf %c\n",x1.a,x1.x.b,x1.x.c,x1.d);
printf("%d %f %lf %c\n",x2.a,x2.x.b,x2.x.c,x2.d);
return 0;
}

这里就是注意镶嵌的结构体要在所镶嵌的结构体之前。


(2)结构体指针

语法:结构体类型名 * 指针变量名

struct name
{
.......;
};
int main()
{
struct name x1;//定义结构体变量。
struct name *ps;//定义相同数据类型的结构体指针。
ps=&x1;//是指针指向已定义的结构体变量。
return 0;
}

“->”箭头运算符:

结构体指针变量名->结构体成员;
当然"(*结构体指针).结构体成员;"也是可以的。
#include <stdio.h>//结构体与指针。
#include <string.h>//setcpy字符串复制函数。(这里提一下在使用字符串时使用库函数更好)
struct date
{
int year;
int month;
int day;
};
typedef struct date date;
struct student
{
int ID;
char name[20];
date birthday;
char sex;
double score;
};
typedef struct student student;
int main()
{
student s1, *p;//指针与其所指对象的类型要一致。
p=&s1;//当指针指向结构体变量时可以有(p->结构体内变量)或者((*p).结构体内变量)等两种形式。
s1.ID=2001;
strcpy(p->name,"Liang");
p->birthday.year=1978;
p->birthday.month=4;
p->birthday.day=20;
p->sex='M';
p->score=100;
printf("%d %s %d.%d.%d %c %.2f\n",p->ID,p->name,p->birthday.year,p->birthday.month,p->birthday.day,p->sex,(*p).score);
return 0;
}

以上便是结构体与指针的一个例子。


(3)结构体数组:

既然结构体是一个数据类型那自然便能够定义数组变量。

语法:

结构体类型名 数组名[常量表达式];

参考代码:

#include <stdio.h>//结构体与数组。(此处还有方法三(*(数组名+下标)).结构体成员)由于后两种方法可读性较差这里就没有列举第三种。
#include <string.h>//调用库函数strcpy。
struct date
{
int year;
int month;
int day;
};
typedef struct date date;
struct student
{
int ID;
char name[20];
date birthday;
char sex;
double score;
};
typedef struct student student;
int main()
{
student st[3]={{1001,"zhang",{1992,5,21},'F',83},{1002,"wang",{1993,6,18},'M',66}};//其中每一个下标都对应一个结构体变量,这里先是定义并赋值了结构体数组变量st[0]与st[1]。
int i;
st[2].ID=1003;//方法一:数组名[下标].结构体成员。
strcpy(st[2].name,"Li");
st[2].birthday.year=1993;
st[2].birthday.month=7;
st[2].birthday.day=22;
st[2].sex='M';
st[2].score=65;
for(i=0;i<3;i++)//方法二:(结构体数组名+下标)->结构体成员。(类比结构体与指针,指针变量就是存储的数组名数组的首地址。)
{
printf("%d %s %d.%d.%d %c %f\n",(st+i)->ID,(st+i)->name,(st+i)->birthday.year,(st+i)->birthday.month,(st+i)->birthday.day,(st+i)->sex,(st+i)->score);
}
return 0;
}

(4)像函数传递结构体:

由于与函数知识类似这里不在说明。

参考代码:

//向函数传递结构体(其实也就差不多就是结构体是用户自定义了数据类型而函数传递需要类型一致)
/*
一:传递结构体成员。与普通的传递方式并没有太大的变化注意数据类型一致即可。
二:传递结构体变量。与结构体变量的数据类型一致也可以使用"."运算符来访问结构体成员。
三:传递结构体地址。 可将结构体指针与结构体数组的首地址作为函数的实参,像函数传递结构体地址。此时函数形参为同类型的结构体指针。
*/
#include <stdio.h>
#include <string.h>
struct student
{
int ID;
char name[10];
double score;
};
typedef struct student student;
void renew_value1(student st)
{
st.ID=1003;
strcpy(st.name,"Jean");
st.score=98;
printf("%d %s %f\n",st.ID,st.name,st.score);
}
/*
函数功能:更新结构体成员值,传地址调用;函数参数:结构体类型指针;函数返回值:无。
*/
void renew_value2(student *pt)
{
pt->ID=1004;
strcpy(pt->name,"Dell");
pt->score=98;
}
int main()//这里没有提及到第一种方法是其与普通常量的传递类似。
{
student st1={1001,"Tom",95},st2={1002,"Jack",93};
printf("%d %s %f\n",st1.ID,st1.name,st1.score);
printf("%d %s %f\n",st2.ID,st2.name,st2.score);
renew_value1(st1);//传值调用方式
renew_value2(&st2);//传地址调用方式
printf("%d %s %f\n",st2.ID,st2.name,st2.score);//通过传递地址进行传递本身的值也发生了变化。
printf("-------------------------------------\n");
printf("%d %s %f\n",st1.ID,st1.name,st1.score);//值未发生改变。
return 0;
}

本文作者:如此而已~~~

本文链接:https://www.cnblogs.com/fragmentary/p/15942011.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   如此而已~~~  阅读(142)  评论(0编辑  收藏  举报
//雪花飘落效果
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起