现在的位置: 首页 > 综合 > 正文

结构体struct简介(下)

2013年10月23日 ⁄ 综合 ⁄ 共 3204字 ⁄ 字号 评论关闭

本文整理自:

http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471
六、结构体指针变量 
   指向一个结构体的指针变量称之为结构体指针变量。 结构指针变量中的值是所指向的结构变量的首地址。 通过结构指针即可访问该结构变量, 这与数组指针和函数指针的情况是相同的结构指针变量说明的一般形式为:
 
struct 结构名*结构指针变量名  
例如,在前面中定义了的stu这个结构体, 如要说明一个指向stu的指针变量pstu,可写为:  
struct stu *pstu;  
  当然也可在定义stu结构时同时说明pstu。与前面讨论的各类指针变量相同,
结构指针变量也必须要先赋值后才能使用。赋值是把结构变量的首地址赋予该指针变量, 不能把结构体类型名赋予该指针变量。
如果boy是被说明为stu类型的结构变量,则: pstu=&boy是正确的,而: pstu=&stu是错误的。 
  结构体类型名结构体变量是两个不同的概念,不能混淆。 结构体类型名只能表示一个结构体的形式,编译系统并不对它分配内存空间。 只有当某变量被说明为这种类型的结构体时,才对该变量分配存储空间。
因此上面&stu这种写法是错误的,不可能去取一个结构名的首地址。 

通过结构体指针变量,能方便地访问结构体变量的各个成员。 
其访问的一般形式为:

 (*结构指针变量).成员名 或为: 结构指针变量->;成员名
 
例如: (*pstu).num或者: pstu->;num 
应该注意(*pstu)两侧的括号不可少, 因为成员符“.”的优先级高于“*”。如去掉括号写作*pstu.num则等效于*(pstu.num),这样,意义就完全不对了。
下面通过例子来说明结构指针变量的具体说明和使用方法。 
示例6.1
struct stu
{
   int num;
   char *name;
   char sex;
   float score;
} boy1={102,"Zhang ping",'M',78.5},*pstu;
main()
{
   pstu=&boy1;
   printf("Number=%d\nName=%s\n",boy1.num,boy1.name);
   printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);
   printf("Number=%d\nName=%s\n",(*pstu).num,(*pstu).name);
   printf("Sex=%c\nScore=%f\n\n",(*pstu).sex,(*pstu).score);
   printf("Number=%d\nName=%s\n",pstu->;num,pstu->;name);
   printf("Sex=%c\nScore=%f\n\n",pstu->;sex,pstu->;score);
}
   本例程序定义了一个结构stu,定义了stu类型结构变量boy1 并作了初始化赋值,还定义了一个指向stu类型结构的指针变量pstu。在main函数中,pstu被赋予boy1的地址,因此pstu指向boy1 。然后在printf语句内用三种形式输出boy1的各个成员值。 从运行结果可以看出:  
结构变量.成员名 
(*结构指针变量).成员名 
结构指针变量->;成员名  
  这三种用于表示结构成员的形式是完全等效的。

七、结构体数组指针变量

结构指针变量可以指向一个结构体数组, 这时结构体指针变量的值是整个结构体数组的首地址。  因为结构指针变量也表示指向结构体数组的一个元素,所以这时该结构指针变量的值其实是该结构体数组0号元素的首地址。设ps为指向结构数组的指针变量,则ps也指向该结构数组的0
号元素,ps+1指向1号元素,ps+i则指向i号元素。 这与普通数组的情况是一致的。 

示例7.1

用指针变量输出结构数组。 
struct stu
{
   int num;
   char *name;
   char sex;
   float score;
}boy[5]={
   {101,"Zhou ping",'M',45},
   {102,"Zhang ping",'M',62.5},
   {103,"Liou fang",'F',92.5},
   {104,"Cheng ling",'F',87},
   {105,"Wang ming",'M',58},
};
main()
{
   struct stu *ps;
   printf("No\tName\t\t\tSex\tScore\t\n");
   for(ps=boy;ps<boy+5;ps++)
   printf("%d\t%s\t\t%c\t%f\t\n",ps->;num,ps->;name,ps->;sex,ps->;score);

}
   在程序中,定义了stu结构类型的外部数组boy 并作了初始化赋值。在main函数内定义ps为指向stu类型的指针。在循环语句for的表达式1中,ps被赋予boy的首地址,然后循环5次,输出 boy数组中各成员值。 
   应该注意的是, 一个结构指针变量虽然可以用来访问结构体变量结构体数组的元素,但是,不能使它指向结构体的一个成员。
也就是说不允许取一个成员的地址来赋予它。
因此,下面的赋值是错误的。 ps=&boy[1].sex;而只能是:ps=boy;(赋予数组首地址) 或者是:
ps=&boy[0];
(赋予0号元素首地址) 
八、结构体变量作为函数参数使用
在函数的参数中使用结构体和一般的变量没有本质的区别,其不同仅仅是在定义上.。

比如:

int ptinrect(struct point p, struct rect r)

{

    return p.x >= r.pt1.x && p.x < r.pt2.x && p.y >= r.pt1.y && p.y < r.pt2.y;

}
九、结构体指针变量作函数参数 
   在ANSI C标准中允许用结构变量作函数参数进行整体传送。 但是这种传送要将全部成员逐个传送, 特别是成员为数组时将会使传送的时间和空间开销很大,严重地降低了程序的效率。 因此最好的办法就是使用指针,即用指针变量作函数参数进行传送。 这时由实参传向形参的只是地址,从而减少了时间和空间的开销。 

示例8.1

计算一组学生的平均成绩和不及格人数。 
struct stu
{
   int num;
   char *name;
   char sex;
   float score;
}boy[5]={
   {101,"Li ping",'M',45},
   {102,"Zhang ping",'M',62.5},
   {103,"He fang",'F',92.5},
   {104,"Cheng ling",'F',87},
   {105,"Wang ming",'M',58},
};
main()
{
   struct stu *ps;
   void ave(struct stu *ps);
   ps=boy;
   ave(ps);
}
void ave(struct stu *ps)
{
   int c=0,i;
   float ave,s=0;
   for(i=0;i<5;i++,ps++)
   {
      s+=ps->;score;
      if(ps->;score<60) c+=1;
   }
   printf("s=%f\n",s);
   ave=s/5;
   printf("average=%f\ncount=%d\n",ave,c);
}

   本 程序中定义了函数ave,其形参为结构指针变量ps。boy 被定义为外部结构数组,因此在整个源程序中有效。在main 函数中定义说明了结构指针变量ps,并把boy的首地址赋予它,使ps指向boy 数组。然后以ps作实参调用函数ave。在函数ave 中完成计算平均成绩和统计不及格人数的工作并输出结果。由于本程序全部采用指针变量作运算和处理,故速度更快,程序效率更高。. 

抱歉!评论已关闭.