2.3关于我们不断说的标记名是可选的那么我们什么时候可以省略什么时候一定不能省略呢如果是上面那种声明定义的方法并且想在一个地方定义结构体设计而在其他地方定义实际的结构体变量那么就必须使用标记可以省略设计的同时就创建该结构体变量但是这种设计是一次性的还有就是引入typedef。这个到后面的定义结构体变量一起说吧关于结构体类型的定义的总结 一般格式就是struct结构体名(也就是可选标记名 { 成员变量 }//使用分号表示定义结束3定义结构体变量3.1之前我们结构体类型的定义结构体的声明只是告诉编译器该如何表示数据但是它没有让计算机为其分配空间。我们要使用结构体那么就需要创建变量也就是结构体变量创建一个结构体变量struct book library看到这条指令编译器才会创建一个结构体变量library此时编译器才会按照book模板为该变量分配内存空间并且这里存储空间都是以这个变量结合在一起的这也是后面访问结构体变量成员的时候我们就要用到结构体变量名来访问。分析struct book的作用在结构体声明中struct book所起到的作用就像int等基础数据类型名作用一样。struct book s1s2*ss定义两个struct book结构体类型的结构体变量还定义了一个指向该结构体的指针其ss指针可以指向s1s2或者任何其他的book结构体变量。其实struct book library等效于struct book{char …….…..}librar这两种是等效的只是第一种可以减少代码的编写量3.2现在还是回到刚才提及的那个问题可选标志符什么时候可以省略其一struct{chartitle[MAXTITL];charauthor[MAXAUTL];floatvalue }library;//注意这里不再是定义声明结构体类型而是直接创建结构体变量了这个编译器会分配内存的//这样的确可以省略标识符也就是结构体名但是只能使用一次因为这是声明结构体的过程和定义结构体变量的过程和在了一起并且个成员变量没有初始化的//如果你想多次使用一个结构体模块这样子是行不通的其二用typedef定义新类型名来代替已有类型名即给已有类型重新命名 一般格式为typedef已有类型 新类型名typedefintElem;typedefstruct{intdate; ..... ..... }STUDENT; STUDENT stu1,stu2;总结一下关于结构体变量的定义1先定义结构体类型后再定义结构体变量 格式为struct结构体名 变量名列表structbook s1s2*ss//注意这种之前要先定义结构体类型后再定义变量2在定义结构体类型的同时定义结构体变量 格式为struct结构体名 { 成员列表 }变量名列表//这里结构体名是可以省的但尽量别省structbook {chartitle[MAXTITL];//一个字符串表示的titile 题目 charauthor[MAXAUTL];//一个字符串表示的author作者 floatvalue;//一个浮点型表示的value价格}s1s2;3直接定义结构体类型变量就是第二种中省略结构体名的情况 这种方式不能指明结构体类型名而是直接定义结构体变量并且在值定义一次结构体变量时适用无结构体名的结构体类型是无法重复使用的也就是说后面程序不能再定义此类型变量了除非再写一次重复的struct落、4对于结构体变量的初始化4.1先回忆一下关于基本数据类型和数组类型的初始化int a 0int array {1,2,3,4};//每个元素用逗号隔开回忆一下数组初始化问题再回到结构体变量的初始化吧关于结构体变量的初始化与初始化数组类似也是使用花括号括起来用逗号分隔的初始化好项目列表注意每个初始化项目必须要和要初始化的结构体成员类型想匹配structbook s1{//对结构体初始化yuwen,//title为字符串guojiajiaoyun,//author为字符数组22.5//value为flaot型};//要对应起来用逗号分隔开来与数组初始化一样4.2加入一点小知识关于结构体初始化和存储类时期的问题如果要初始化一个具有静态存储时期的结构体初始化项目列表中的值必须是常量表达式如果存储时期是自动的那么列表的值就不必是常量了关于这点在讲存储类时期的时候在分析4.3注意如果在定义结构体变量的时候没有初始化那么后面就不能全部一起初始化了意思就是/////////这样是可以的在定义变量的时候就初始化了structbook s1{//对结构体初始化guojiajiaoyun,//author为字符数组yuwen,//title为字符串22.5};/////////这种就不行了在定义变量之后若再要对变量的成员赋值那么只能单个赋值了structbook s1; s1{guojiajiaoyun,//author为字符数组yuwen,//title为字符串22.5};//这样就是不行的只能在定义的时候初始化才能全部赋值之后就不能再全体赋值了只能单个赋值只能 s1.title yuwen;........//单个赋值4.4对于结构体的指定初始化《这个只存在于c99》5访问结构体成员5.1结构体就像一个超级数组在这个超级数组内一个元素可以是char类型下个元素就可以是flaot类型再下个还可以是int数组型这些都是存在的。在数组里面我们通过下标可以访问一个数组的各个元素那么如何访问结构体中的各个成员呢用结构成员运算符点.就可以了结构体变量名.成员名;注意点其结合性是自左至右的它在所有的运算符中优先级是最高的例如s1.title指的就是s1的title部分s1.author指的就是s1的author部分,s1.value指的就是s1的value部分。然后就可以像字符数组那样使用s1.title,象使用float数据类型一样使用s1.value注意s1虽然是个结构体但是s1.value却是float型的因此s1.value就相当于float类型的变量名一样按照float类型来使用例如printf(“%s\n%s\n%f”,s1.title,s1.author,s1.value);//访问结构体变量元素注意scanf(“%d”,s1.value); 这语句存在两个运算符和结构成员运算符点按照道理我们应该将s1。value括起来因为他们是整体表示s1的value部分但是我们不括起来也是一样的因为点的优先级要高于。5.2如果其成员本身又是一种结构体类型那么可以通过若干个成员运算符一级一级的找到最低一级成员再对其进行操作结构体变量名.成员.子成员………最低一级子成员;structdate {intyear;intmonth;intday; };structstudent {charname[10];structdate birthday; }student1;//若想引用student的出生年月日可表示为student.brithday.yearbrithday是student的成员year是brithday的成员5.3整体与分开5.3.1可以将一个结构体变量作为一个整体赋值给另一相同类型的结构体变量可以到达整体赋值的效果这个成员变量的值都将全部整体赋值给另外一个变量5.3.2不能将一个结构体变量作为一个整体进行输入和输出在输入输出结构体数据时必须分别指明结构体变量的各成员总结除开“相同类型的结构体变量可以相互整体赋值”外其他情况下不能整体引用只能对各个成员分别引用6结构体数组这个在国二里面常考的类型只要考结构体就离不开结构体数组和成员的访问当然也只是简单的操作6.1为什么要引用结构体数组显然在上面的book类型的结构体 每本书就需要用一个book类型的结构体变量来描述若是要描述两本书需要使用两个这样的变量依次类推因此要使用一个该结构体的数组来表示这些图书并且数组就是存储一组具有相同类型的数据因此就有了结构体数组的出现注意本置6.2声明结构体数组与普通的数组声明一样int a;int为元素的数据类型a为数组名 【10】表示申请了10的int单元的内存再看结构体声明struct book library;是不是类似struct book为数组元素的数据类型library为数组名为申请了10个struct book单元的内存解释声明library为一个具体10个元素的数组并且每个元素都book类型的结构因此可以得到library,library…….都是单独独立的一个book结构注意library本身不是结构体名而是一个数组名6.4结构体数组的初始化两种初始化就是在定义的时候赋值的两种情况6.3访问结构体数组的成员规则在结构体名后加点运算符然后再是成员名library.title;//表示第5个元素的title成员library是结构体变量名title就是成员名library.titlt;//注意title是数组类型第5个数组元素的title成员的第4个字符总结library//book结构体的数组library[2]//数组的第二个元素一个book结构体类型的变量名library[2].title//char数组结构体数组的第二个元素的title成员library[2].title[4]//表示一个字符结构体数组的第二个元素的title成员的第四个字符7;指向结构体的指针7.1使用指向结构体的好处就像指向数组的指针一样它比数组本身更容易操作指向结构体的指针通常也比结构体本身更容易操作声明和初始化结构体指针声明struct book * him规则就是struct 结构体名 * 指针名这个声明不是建立一个新的结构体而是创建了一个指针类型的him指针变量他可以指向任何现有的book类型的结构体him library指针him正指向结构体library如何使用him来取得library的一个成员呢方法一引入一个运算符-后跟-运算符的结构体指针和后跟.点运算符的结构体名是一样操作的注意一点的是不能使用him.成语因为him不是结构体名总结 -只用于结构体指针访问成员.点只用于结构体名访问成员方法二如果himlibrary那么himlibrary因为和是一个互逆的运算符取地址*取值》library.value 等价于 *him.value注意必须使用圆括号优先级问题然后都与him.value是一个作用对于考国二懂得上面的也就差不多了足够了8向函数传递结构体信息8.1传递结构体成员只要结构体成员是具有单值的数据类型及int等基础数据类型就可以把它作为参数传递给一个接受这个特定参数类型的函数注意这个只能实现访问不能修改8.2使用结构体地址注意如果不修改值则设置为const8.3使用结构体作为参数传递其中s也是结构体变量并且为s1结构体变量的副本。总结结构体指针使用-运算符访问成员结构体名使用.点运算符访问成员要想通过调用函数修改实参结构体变量的值只能传递地址通过指针来修改直在地址上修改8.4结构体之间的双向通信先注意这个c语言中对于结构体变量是可以整体赋值的无论其成员是怎样的传递地址使用结构体指针接收用于访问不做修改const限制修改结构体作为参数传递不能成功修改实参只能访问结构体作为参数修改结构体并且返回类型也为结构体达到修改的目的传递地址使用结构体指针接收用于修改不使用const限制修改通常我们是使用结构体指针的如果不修改那么我们会使用const修改9在结构体中使用字符数组还是字符指针来存储字符串答案先给出尽量使用字符数组9.1使用字符数组#defineMAXTITL 100#defineMAXAUTL 100structbook {chartitle[MAXTITL];//一个字符串表示的titile 题目 charauthor[MAXAUTL];//一个字符串表示的author作者 floatvalue;//一个浮点型表示的value价格}; 字符串的存储在结构体内部的 结构体总分配200个字节的内存给这两个字符串9.2使用字符指针structbook {char*titlechar* author }; 这里的字符串是存储在编译器认为存储字符串常量的任何地方这个结构体中存放的只有两个地址而已值分配8分字节结构体不为字符串分配任何内存存储空间因此这时候在输入的时候存在了一个潜在的危险scanf(%s,s.last);//把字符串放到由s.last指向的内存中因为这是一个未初始化的变量因此该地址是可以指向任意大小的因此此时就是一个潜在的危险总结因我们最好是使用字符数组来存储字符串10结构体和指针和malloc函数这个可以看我之前的博客http://blog.csdn.net/zw1996/article/details/53708591关于结构体的介绍就暂时到这里时间有点急学得也不深所以暂时先补充到这里下次补上还有未补充的内容1结构体数组的函数2结构体内容保存在文件当中3一些结构体的例子