Linux C语言程序设计(四)——枚举与结构体

1、结构体

        结构体不同于我们之前了解到的基本数据类型,结构体数据类型是一种复合数据类型,它可以包括一些基本的数据类型。

        复合数据类型一方面可以从整体上当作一个数据使用,另一方面也可以分别访问它的各组成单元,复合数据类型的这种两面性提供了一种数据抽象。如果学习过java这样的面向对象的语言,会对结构体这样的抽象数据结构了解得比较深刻。比如,如果我们在二维坐标系上有一个点,那么如何描述这个点呢?很显然,它有横坐标和纵坐标,我们使用x和y表示。比如(5,2)就表示横轴为5,纵轴为2。换到我们的程序语言中,单纯的整形或者浮点型这样的单一数据结构已经无法满足需求,我们需要寻找另外的一种方式。

那么这个时候,我们的结构体就用上了,我们可以使用如下的数据结构:

struct point_struct {
	double x, y;
};

point_struct 表示的是点这个对象名称,这里我们称之为结构体对象名称。其中的x和y分别代表横纵坐标,如果我们想声明两个点a、b,那么我们会使用如下的代码:

struct point_struct a,b;

我们来看一段实例代码,如下:

#include <stdio.h>
int main(void)
{
	struct point_struct { double x, y; } z;
	double x = 3.0;
	z.x = x;
	z.y = 4.0;
	if (z.y < 0){
		printf("z=%f%fi\n", z.x, z.y);
	}else{
		printf("z=%f+%fi\n", z.x, z.y);
	}
	return 0;
}

2、数据抽象

数据抽象是一个比较难解释的概念,我们上文讲到如何使用结构体描述一个点,这里我们将介绍,如何使用结构体来抽象一个函数。

我们知道,在C语言中,前辈先人为我们封装了很多不同的函数库,其中数学函数库是非常大的一类,我们也经常使用。比如我们要做两个数的加减乘除,就可以找到相应的函数来计算,而不必再手动造轮子。但是学习要究其原理,我们今天就来手动造一个加减乘除的轮子。

如上,我们应该先描述一个点,我们暂且将两个数放在一起称之为点,与上文一致,不再描述。我们定义一些函数,加减乘除,举例加法的函数如下:

double addFunc(struct point_struct num){
	return num.x + num.y;
}

如上,我们传递一个结构体数据类型给这个addFunc函数,使用它的x点和y点数值进行相加,然后返回给调用者。我们测试一下:

#include <stdio.h>
int main(void)
{
	struct point_struct { double x, y; } z;
	
	z.x = 3.0;
	z.y = 4.0;

	printf("z=%f\n", addFunc(z));

	return 0;
}


3、枚举标志

        在上文中,我们使用了两次结构体这样的概念,一次是点,一次是类似点(两个是相互独立的数字)。那么,既然这个数据结构可以同时适用于两种不同的应用场景,我们能不能将之合并使用,而用一个标志位来进行一定的区分呢?答案是肯定的。

        于是这里就引入我们的枚举类型,如下:

enum coordinate_type { POINT, NUM };
struct complex_struct {
	enum coordinate_type t;
	double a, b;
};

        enum关键字的作用和struct关键字类似,把coordinate_type这个标识符定义为一个Tag,只不过struct complex_struct表示一个结构体类型,而enum coordinate_type表示一个枚举类型。

        枚举类型的成员是常量,它们的值编译器自动分配,例如定义了上面的枚举类型之后, RECTANGULAR就表示常量0, POLAR就表示常量1。


有一点需要注意,结构体的成员名和变量名不在同一命名空间,但枚举的成员名和变量名却在同一命名空间,所以会出现命名冲突。如下的命名就是不合法的:

int main(void)
{
	enum coordinate_type { RECTANGULAR = 1, POLAR };
	int RECTANGULAR;
	printf("%d %d\n", RECTANGULAR, POLAR);
	return 0;
}

4、嵌套结构体

        结构体也是一种递归定义:结构体由数据类型定义,因为结构体的成员具有数据类型,而数据类型由结构体定义,因为结构体本身也是一种数据类型。换句话说,结构体也可以嵌套。例如我们在复数的基础上定义复平面上的线段:

struct Segment {
	struct complex_struct start;
	struct complex_struct end;
};

嵌套结构体可以嵌套地初始化。例如:

struct Segment s = {{ 1.0, 2.0 }, { 4.0, 6.0 }};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值