结构和其他数据形式

结构和其他数据形式

建立结构声明:

如下:

struct book{
	char title[MAXTITL];
	char author[MAXAUTL];
	float value;
};

这里已经声明了一个结构;
在后续的程序中声明符合这个类型的结构变量可以这样声明:
struct book library;这样library就是一个book类型的结构变量,声明结构变量时struct book就相当于int float····

初始化结构:

初始化结构体同初始化变量和数组一样,如下;

struct book library ={
					"asdfghjkk",
					"qwertyuiop",
					1.95
}

结构体中各变量之间用”,“分开。

注意 初始化结构和类别储存期
第 12 章提到过,如果初始化静态存储期的变量(如,静态外部链接、静态内部链接或静态无链接),必须使用常量值。这同样适用于结构。如果初始化一个静态存储期的结构,初始化列表中的值必须是常量表达式。如果是自动存储期,初始化列表中的值可以不是常量。

访问结构体中的成员:

访问结构体中的成员要用到”.“运算符;如library. title,library.value;这样library.title就相当于一个字符数组,你可以对它进行任何操作;

结构的初始化器:

就是利用”.“运算符对结构体中的部分成员可以赋值,如:

struct book gift = {
	.value = 25.99,
	.author = "James Broadfool",
	.title = "Rue for the Toad"
};

另外,对某一个成员第二次赋值可以覆盖上一次的值,即第二次赋的值才是真正的值;如:

struct book gift = {
	.value = 18.90,
	.author = "Philionna Pestle",
	0.25
};

value最终的值是0.25,因为在这个结构体中value紧跟在author之后;

结构数组:

显然,每本书的基本信息都可以用一个 book 类型的结构变量来表示。为描述两本书,需要使用两个变量,以此类推。可以使用这一类型的结构数组来处理多本书:

struct book{
	int a;
	int b;
	char a[100]
}b[100]; 

声明结构数组:

1,同上
2,struct book b[1000];

嵌套结构:

有时,在一个结构中包含另一个结构(即嵌套结构)很方便。例如,Shalala Pirosky 创建了一个有关她朋友信息的结构。显然,结构中需要一个成员表示朋友的姓名。然而,名字可以用一个数组来表示,其中包含名和姓这两个成员。如下:

/* 嵌套结构示例 */
#include <stdio.h>
#define LEN 20
const char * msgs[5] =
{
    "   Thank you for the wonderful evening, ",
    "You certainly prove that a ",
    "is a special kind of guy. We must get together",
    " and have a few laughs"
};

struct names {
    char first[LEN];
    char last[LEN];
};

struct guy {
    struct names handle;
    char favfood[LEN];
    char job[LEN];
    float income;
};

int main(void)
{
	struct guy fellow = {
	    {
	        "Ewen",
	        "Villard"
	    },
	    "grilled salmon",
	    "personality coach",
	    68112.00
	};

	printf("Dear %s, \n\n",fellow.handle.first);
	printf("%s%s.\n",msgs[0],fellow.handle.first);
	printf("%s%s\n",msgs[1],fellow.job);
	printf("%s\n",msgs[2]);
	printf("%s%s%s",msgs[3],fellow.favfood,msgs[4]);
	if(fellow.income > 150000.0)
        puts("!!");
    else if (fellow.income > 75000.0)
        puts("!");
    else
        puts(".");
    printf("\n%40s%s\n"," ","See you soon,");
    printf("%40s%s\n"," ","Shalala");

	return 0;
}

下面是程序的输出:

Dear Ewen,

   Thank you for the wonderful evening, Ewen.
You certainly prove that a personality coach
is a special kind of guy. We must get together
 and have a few laughsgrilled salmon(null).

                                        See you soon,
                                        Shalala

访问嵌套结构的成员;
(fellow.handle).first

指向结构的指针:

声明一个结构指针:struct guy *him;
也可以这样写:him = &barney(barney是一个guy类型的结构)
和数组不同,结构名并不是结构地址,所以要加&


用指针访问成员:

指针him指向结构变量fellow[0],如何通过him 获得fellow[0]成员的值,
第一种方法是:
使用 -> 运算符
如果him==&bareny,那么him->income即是bareny.income
如果him==&fellow[0],那么him->income即是fellow[0].income
在本例中,him是一个指针,但是him->income是该指针所指向结构的一个成员,所以在该例中,him->income是一个float类型的变量。
第二种方法是:如果him==&fellow[0]那么him==fellow[0],因为&和是一对互逆运算符,因此,可以做以下替代:fellow[0].income==(*him).income必须使用圆括号,因为.运算符比星号运算符的优先级高。

向函数中传递结构的信息:

1, 传递结构成员:可以将结构体中的成员作为函数参数;
2,传递结构的地址:将结构(或结构中某个成员)地址作为参数;
3,传递结构:将结构作为参数;

联合:

联合体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的联合体,但是任何时候只能有一个成员带有值。联合体提供了一种使用相同的内存位置的有效方式。
定义联合体 为了定义联合体,您必须使用 union 语句,方式与定义结构类似。union 语句定义了一个新的数据类型,带有多个成员。union 语句的格式如下:

union [union tag]
{
   member definition;
   member definition;
   ...
   member definition;
} [one or more union variables];

union tag 是可选的,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在联合体定义的末尾,最后一个分号之前,您可以指定一个或多个联合体变量,这是可选的。

使用联合:

同结构体一样,用“.”运算符,但联合体只能储存一个值,这与结构不同,

fit.digit = 23; //把 23 储存在 fit,占2字节
fit.bigfl = 2.0; // 清除23,储存 2.0,占8字节
fit.letter = 'h'; // 清除2.0,储存h,占1字节

枚举类型:

可用枚举类型来声明符号名称来表示整形常量,使用enum关键字,枚举类型目的是提高程序的可读性,它的语法与结构语法相同,

enum spectrum {red, orange, yellow, green, blue, violet};
enum spectrum color;

red代表0,orange代表1,以此类推,枚举类型通常可以与switch语句一起使用
enum用法
枚举类型的目的是为了提高程序的可读性和可维护性。

因为枚举类型是整数类型,所以可以在表达式中以使用整数变量的方式 使用enum变量。它们用在case语句中很方便。

注意,枚举类型只能在内部使用。如 果要输入color中orange的值,只能输入1,而不是单词orange。或者,让程序 先读入字符串"orange",再将其转换为orange代表的值。

/* enum.c -- 使用枚举类型的值 */
#include <stdio.h>
#include <string.h>  // 提供 strcmp()、strchr()函数的原型
#include <stdbool.h>  // C99 特性
char * s_gets(char * st, int n);
enum spectrum { red, orange, yellow, green, blue, violet };
const char * colors [] = { "red", "orange", "yellow",
"green", "blue", "violet" };
#define LEN 30
int main(void)
{
char choice[LEN];
enum spectrum color;
bool color_is_found = false;
puts("Enter a color (empty line to quit):");
while (s_gets(choice, LEN) != NULL && choice[0] != '\0')
{
for (color = red; color <= violet; color++)
{
if (strcmp(choice, colors[color]) == 0)
{
color_is_found = true;
break;
}
}
if (color_is_found)
switch (color)
{
case red: puts("Roses are red.");
break;
case orange: puts("Poppies are orange.");
break;
case yellow: puts("Sunflowers are yellow.");
break;
case green: puts("Grass is green.");
break;
case blue: puts("Bluebells are blue.");
break;
case violet: puts("Violets are violet.");
break;
}
else
printf("I don't know about the color %s.\n", choice);
color_is_found = false;
puts("Next color, please (empty line to quit):");
}
puts("Goodbye!");
return 0;
}
char * s_gets(char * st, int n)
{
char * ret_val;
char * find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n');  // 查找换行符
if (find)          // 如果地址不是 NULL,
*find = '\0';     // 在此处放置一个空字符
else
while (getchar() != '\n')
continue;     // 清理输入行
}
return ret_val;
}

当输入的字符串与color数组的成员指向的字符串相匹配时,for循环结 束。如果循环找到匹配的颜色,程序就用枚举变量的值与作为case标签的枚 举常量匹配

typedef:

typedef可用于为某一类型自定义名称,相当于改名字的关键字,如:
typedef int x;
那么在这条声明之后int a=1与x a=1相同,都是设置一个a变量;
用typedef来命名一个结构类型时,可以省略该结构的标签:

typedef struct {double x; double y;} rect;

typedef常用于给复杂类型命名,使用时记住typedef没有创建任何新类型,它只是将原类型改了个名


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值