关闭

c语言中的结构体

484人阅读 评论(0) 收藏 举报
分类:

前言

结构体在c语言中占据半壁江山,所以一定要好好学,在以后的数据结构中几乎全部是在玩结构体,包括用c语言写的其他软件(nginx, php)等,基本通篇都是在用到结构体。

什么结构体

c语言中有基本的数据类型外,还有数组类型,但是这些类型都比较单一,定义成什么类型后,就是这个类型了。数组也是。数组里面的所有的类型都是同一个类型。

那么,为了解决在一个定义的变量中出现多种不同的数据类型,就出现了结构体。就是在结构体内可以允许包含各种各样不同的数据类型。

结构体的申明

结构体用struct关键字来申明,比如,举个例子,申明一个人:

struct People {
    double height;
    char name[10];
    int age;
}

每个成员都用自己的类型申明,并且用;结尾。这样,就申明来一个结构体变量,这种情况下是不咱用存储空间的。只要在定义一个结构体变量的时候,才会分配空间。

定义一个结构体变量

有很多种方式来申明一个变量为结构体变量,第一种是最常见的:

struct People yangyi;

这样我就定义了一个变量yangyiPeople 类型的结构体变量。

还一种是在申明的同时就给定义了:

struct People {
    double height;
    char name[10];
    int age;
} yangyi;

像这样,直接跟在最后一个}后面写上去,就定义好了一个变量,和上面的那种方式是一样的。

还一种方式呢,是直接把结构体的名字都省略掉:

struct {
    double height;
    char name[10];
    int age;
} yangyi;

不过不推荐用这种写法,虽然看起来比较精简,但是,它却不能重复利用了,是一次性的定义了一个结构体变量yangyi,不能拿来定义另外的变量了。

结构体的初始化

上面,我们申明了结构体,并定义了一个这个类型的结构体变量,现在就是初始化了,也就是给这个结构体赋值,

struct People yangyi = {176.56,"yangyi",20}; //第一种初始化方式

{}花括号把里面的包含的变量依次一个一个按照他们的类型来赋值。

一定要注意的是:结构体变量的定义和赋值初始化必须是连在一起的,因为学过其他的语言的,很容易想当然的犯这个错误,将定义和初始化赋值分开写;

像下面这种就是错误的:

struct People yangyi;
yangyi = {176.56,"yangyi",20}; //错误

必须要连着定义和初始化一起写,所以,根据上面的3种方式,还有2种方式来初始化:

struct People {
    double height;
    char name[10];
    int age;
} yangyi = {176.56,"yangyi",20}; //第二种初始化方式

struct {
    double height;
    char name[10];
    int age;
} yangyi = {176.56,"yangyi",20}; //第三种初始化方式

结构体的访问使用

上面申明,定义,赋值都可以了,现在就是看如何使用它了。访问结构体中的成员采用.来取。

yangyi.height;
yangyi.name;
yangyi.age;

这样子来取,是不能直接打印这个结构体的,就和数组一样,你不能一次性的把整个数组打印出来,只能一个一个的循环遍历,c语言这一点很蛋疼。

所以,我们既然能去粗来,就可以打印:

printf("%f", yangyi.height); //%f 对应于打印输出double类型
printf("%s", yangyi.name); //%s 字符串
printf("%d", yangyi.age); // %d 整形数字

既然,用.可以取值,照说也应该可以赋值啊。上面说了。整体的赋值必须在定义的时候就一起完成了,但是单独分来给某一个成员赋值,也是可以的:

yangyi.age = 21;
yangyi.height=18.334;

这样也是可以的。但是注意了,千万不能这样:

yangyi.name="dashuaige"; //错误的。

这样是会报错的,因为确实存在的严重的语法错误。name是 一个字符串数组,这样赋值,前面也说过,相当于是在给name整个数组的地址(&name)赋值,肯定是错误的。

那如何给name赋值呢?除了上面说的定义的时候就赋好值。如果是想用.符号复制,就只能想赋值数组那样,一个一个的赋了:

yangyi.name[0] = 'y';
yangyi.name[1] = 'a';
yangyi.name[2] = 'n';
yangyi.name[0] = 'g';
yangyi.name[3] = 'y';
yangyi.name[4] = 'i';
yangyi.name[5] = '\0';

上面是比较笨的方法,还有一种是用到c 中的函数了,拷贝

strcpy(yangyi.name, "zhliao2");  //这里是对字符串复制

结构体数组

既然,结构体也是一种类型,那么几个相同的结构体就可以组成一个结构体数组了。

申明都是一样,主要是定义的时候怎么定义:

struct People student[2] = {186.777, "yangyi", 21 , 156.444, "liming", 20}; 

和定义数组时一模一样,用[2]这种方式,来定义成员的长度,用{}扩起来成员的初始化值。

好像 有点不清楚,可以里面再用1个{}阔起来:

struct People student[2] = {{186.777, "yangyi", 21} , {156.444, "liming", 20}}; //清晰一点

结构体数组的取值业一样,只不过需要加上,取的是数组中第几个的值:

student[0].height;
student[0].age;
student[1].height;
student[1].name;

结构体指针

这个是个难道,也是个重点。c 语言的牛逼之处就是用这个指针,我擦,各种瞎鸡巴乱指,把人搞的云里雾里。结构体里面也他妈有指针。当然指针在另外的章节会仔细的讲。

结构体体针就是申明一个为指针类型的结构体:

struct People yangyi = {176.56,"yangyi",20};
struct People *sb;
sb = &yangyi;

不懂指针的取温洗一下。这样三句话下来,就定义好了,一个指针类型的结构体变量sb, 并且,把它指向了变量yangyi。这样,我们操作sb就可以做各种事情了。

比如。我想取值,就有很多种方式:

yangyi.name; //正常的用法
(*sb).name; //指针取
sb->name;  //用指针的取值操作符->也可以。

上面的三者是等价的。

换成是数组类型的结构体,指针怎么指呢?

struct People yangyi[2] = {{186.777, "yangyi", 21} , {156.444, "liming", 20}}; //数组类型
struct People *sb;
sb = &yangyi;

我们知道用指针指向数组,其实就是指向数组的第一个值,也就是sb ->&yangyi[0]。

所以,这个时候sb 是指向数组的第一个元素的:

sb->name; // yangyi
sb++; //指针后移,就指向第2个元素了
sb->name; //liming

define 预处理

说完结构体,再来说下预处理这个关键字define。它一般放在一个文件的头部,定义好乱之后,其他地方可以直接用了,其实就是其他语言中的常量的定义:

#define WE 123 //因为还是预处理阶段,还不属于c语法,可以不用;结尾
#define PI 3.14 //定义pi

# define 这个扬子来预处理定义一个变量。

值得主要的是:这个预处理是再c语言整个周期的第一步完成的,也就是在预处理阶段去替换。

这里写图片描述

关于define的其他用法,以后想到再慢慢讲,比较简单。

typedef

typedef 用开定义变量的类型的别名。就是alias。比如,int我想给它定义一个别名 tni,就可以这样:

typedef int tni;   //结尾一定要加; 因为已经是c语言的语句语法了

以后,我们就可以 用tni来申明和定义一个整型:

tni a = 123; // 等同
int b =123; //

如果仅仅是用来给简单的类型取别名,就太傻逼和多此一举了,其他它真正的用途是给一些复杂的数据类型,数据结构取别名,方便调用。比如,给结构体struct取别名:

typedef struct People {
    double height;
    char name[10];
    int age;
} person;

上面我们就给结构体struct People 取了一个别名person。之后,我们定义结构体的时候,就可以直接用person了,你看程序员多懒!!!

person yangyi = {176.56,"yangyi",20};
struct People yangyi = {176.56,"yangyi",20}; //等同

如果用了别名,那这样看来,这个struct的名字People的名字可以省略了:

typedef struct {
    double height;
    char name[10];
    int age;
} person; #省略了名字

person yangyi = {176.56,"yangyi",20};

等指针学了再来讲typedef与指针的关系。。。待续。。

1
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:330273次
    • 积分:5295
    • 等级:
    • 排名:第5104名
    • 原创:202篇
    • 转载:4篇
    • 译文:0篇
    • 评论:39条
    最新评论