c语言中的结构体

原创 2015年07月06日 23:35:00

前言

结构体在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与指针的关系。。。待续。。

相关文章推荐

C语言结构体实现方法

  • 2015年03月21日 01:24
  • 548KB
  • 下载

C语言 循环结构体设计

  • 2017年10月21日 09:42
  • 1.25MB
  • 下载

C语言函数指针,结构体阶段总结

1.数组与函数 1)        数组元素作参数 large(int x, int y){...}; large(a[2], a[3]);   2)        数组名作参数 计算...

C语言结构体

  • 2013年03月27日 15:50
  • 508KB
  • 下载

c语言结构体

  • 2013年12月08日 13:47
  • 705KB
  • 下载

对嵌入式开发C语言结构体的一点总结

今天冬至居然不上班,公司的良心啊!这回有心情写博客和日志了,好了,废话不多说。直接看下文: 鉴于嵌入式开发过程中,C语言结构体的使用当然是必不可少。话说,基础什么的比你会更牛逼的算法更重要,基础不牢...

【C语言】linux网络编程—hostent结构体,gethostbyname的使用

使用gethostbyname函数获取 hostent 域名结构体 最简单的情况,这里面不包括出错处理,异常等的处理: #include #include #include #include...

结构体 c语言 进制转换

  • 2015年11月07日 16:06
  • 17KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c语言中的结构体
举报原因:
原因补充:

(最多只允许输入30个字)