1嵌套结构
struct name{ //第一个结构
char first[LEN];
char last[LEN];
};
struct guy{ //第二个结构
struct name handle; //嵌套结构【注意是如何声明的】
char favfoodp[LEN];
char job[LEN];
float income;
};
int main(void)
{
struct guy fellow = { //初始化一个结构变量
{“Ewen”,"Yang"},
"grilled salmon",
"personality coach",
68112.0
};
//如何访问嵌套结构呢?
printf("first name 为%s\n",fellow.handle.first); //两个.访问。
}
2.指向结构的指针
2.1使用指向结构的指针的好处:
2.1.1就像指向数组的指针,且比数组本身更容易操作,指向结构的指针通常比结构本身更容易操控;
2.1.2在一些早期的C中,结构不能作为参数传递给函数,但是可以传递指向结构的指针;
2.1.3即使能传递结构,但是传递指针通常效率更高。
2.14一些用于表示数据的结构中包含指向其他结构的指针。
2.2开始定义指向结构的指针
#include <stdio.h>
#define LEN 20
struct name {
char first[len];
char last[len];
};
struct guy{
struct name handle; //嵌套结构【注意是如何声明的】
char favfoodp[LEN];
char job[LEN];
float income;
};
int main(void)
{
//学会结构数组的初始化
struct guy fellow[2] =
{
{
{“Ewen”,"Yang"},
"grilled salmon",
"personality coach",
68112.0
},
{
{“Ewen”,"Wen"},
"grilledddd salmonaaa",
"personality coac123h",
48112.0
};
};
struct guy * him;//这是一个指向结构的指针
}
指向结构的指针内容请看:C中.与->的区别
3.向函数传递结构信息
函数的传递参数,其实每一个值都是一个数字,比如:int类型,float类型,ASCII编码字符码,或者一个地址。
结构的变量名并不是其地址的别名,与数组不同。
传递的3种方式:
1.传递结构成员
#include <stdio.h>
#include <stdlib.h>
#define FUNDLEN 50
struct funds{
char bangk[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(double x,double y)
int main()
{
struct funds stan = {
"aaaaaa",
54.67,
"iiijjj",
66.55
};
printf("total = %.2f\n",sum(stan.savefund,stan.bankfund));
return 0;
}
double sum(double x,double y)
{
return x+y;
}
2.传递结构的地址
#include <stdio.h>
#include <stdlib.h>
#define FUNDLEN 50
struct funds{
char bangk[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(const struct funds * );//参数是一个指针
double sum(double x,double y) ;
int main()
{
struct funds stan = {
"aaaaaa",
54.67,
"iiijjj",
66.55
};
//传递结构地址
printf("total = %.2f\n",sum(&stan)); //注意理解这里。就是将money指针指向stan 等价于 money = &stan。那么就可以后续操作了。
return 0;
}
//传递结构地址的方式
double sum(const struct funds * money) //这里把指向funds的指针申明为指向const的指针,因为不去改变这个结构中的变量。
{
return (money->bankfund + money->savefund);
}
3传递结构的方式:
#include <stdio.h>
#include <stdlib.h>
#define FUNDLEN 50
struct funds{
char bangk[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(struct funds moolah);
int main()
{
struct funds stan = {
"aaaaaa",
54.67,
"iiijjj",
66.55
};
printf("total = %.2f\n",sum(stan));
return 0;
}
double sum(struct funds moolah)
{
return (moolah.bankfund + moolah.savefund);
}
在(传递结构的方式)main函数中调用sum的时候,编译器根据funds模板创建一个名为moolah的自动结构变量,然后,该结构的各个成员被初始化为stan结构变量相应成员值得副本。因此,程序使用原来结构的副本进行计算。然而在传递指针的程序使用的是原始的结构进行计算。
4其他结构特性
其他特性都讲了些什么呢?
4.1现在的C允许吧一个结构赋值给另一个结构,但是数组不能这样做,也就是说n_data和o_data都是相同类型的结构,可以这样做:
o_data = n_data;//把一个结构赋值给另一个结构
//这条语句时把n-_data的每个成员的值赋值给o_data的相应的成员。即使成员是数组,也能完成赋值。
4.2现在的C,函数不仅能把结构本身作为参数传递,还能把结构作为返回值返回。把结构作为函数参数,可以把结构的信息传送给函数;把结构作为返回值的函数,能把结构的信息从被调函数传回主调函数。结构指针也允许这种双向通信。(详细参考《C Primer Plus P454》)
5.结构和结构指针的选择
问题:假如要编写一个与结构相关的函数,是用结构指针作为参数,还是用结构作为参数和返回值?两者各有优缺点。
把指针作为参数有两个优点和一个缺点:
优点:
(1)执行起来很快
(2)只需要传递一个地址
缺点:
(1)无法保护数据(被调函数中的某些操作可能会意外影响原来结构中国的数据,但是,ANSI C新增了const限定符解决了这个问题。)
**把结构作为参数传递的优点:**函数处理的是原始数据的副本,这保护了数据,另外,代码格式也更加清楚。
传递结构的缺点:浪费时间和存储空间。
6.结构中的字符数组和字符指针
首先,我们可以在结构中用字符数组来存储字符串,也可以用指向char类型的指针来代替字符数组,那么它们两者有什么区别呢?
#define LEN 20
struct name{
char first[LEN];
char last[LEN];
};
struct pname{
char * first;
char * last;
};
struct name veep = {"Talia","Summers"};
struct pname treas= {"Brad","Fallingjaw"};
printf("%s and %s\n",veep.first,treas.first);
//对应这个treas.first,是没有问题的,因为treas是结构体变量,直接用.的形式去访问成员,无论成员是什么类型,都没有关系,此处是指针类型,照样访问。
思考:对于struct name类型的结构变量veep,以上字符串都存储在结构内部,结果总共要分配40 字节存储姓名。然而对于struct pname类型的结构变量treas,以上字符串存储在编译器存储常量的地方。***结构本身值存储两个地址,在我们的系统中共占16个字节。***(加粗倾斜的我没怎么理解,看到的请指导一下。)尤其是,struct pname结构不用为字符串分配任何存储空间。它使用的是存储在别处的字符串(如:字符串常量或者数组中的字符串)。说白了,在pname结构变量中的指针应该只用来在程序中管理哪些已分配和在别处分配的字符串。
struct name accountant;
struct pname attorney;
puts("Enter the last name of your accountant:");
scanf("%s",accountant.last);
puts("Enter the last name of your attorney:");
scanf("%s",attorney.last);//这里有一个潜在的危险
对于accountant而言,它的名存储在accountant结构变量的last成员中,但是对于attorney而言呢?把字符串放到了attorney。last表示的地址上,但是这个地址没有初始化,地址可以是任何值,一次程序可以把名存放在任何位置,就要潜在危险。
因此,如果要使用结构存储字符串,用字符数组作为成员比较简单,用指向char的指针也行,但是误用会导致严重的问题。