结构和联合

来源:互联网 发布:淘宝首图背景素材 编辑:程序博客网 时间:2024/05/17 05:58

数组:相同类型的元素的集合。数组元素可以通过下标访问,因为数组的元素长度相同。

结构体:结构各个成员可能具有不同的类型。


结构声明

在声明结构时,必须列出它包含的所有成员。

struct {            int  a;            char b;            float  c;}x;

struct{int  a;char b;float c;}y[20], *z;

z是指针,它指向这个类型的结构。  

警告:这两个声明被编译器当作两种截然不同的类型,即使它们的成员列表完全相同,因此,变量y和z的类型和z类型不同,所以:

z = &x;

这样是非法的。

结构成员的间接访问

         在用指针对结构体的间接访问操作的时候,如果用点操作符访问成员变量的时候,由于点操作符的优先级高于间接访问操作符,所以你必须在表达式中使用括号,确保间接访问操作首先执行。例如:

void  function( struct COMPLEX * cp);
函数可以使用(*cp).f 来访问这个变量所指向的结构的成员f。

但是,由于这样会很烦琐,C语言又提供了另一种方法那就是 -> 来间接访问结构成员。例: cp -> f


结构体的自引用

struct    SELF_REF1{inta;structSELF_REF1b; //这里是错误的写法,因为这样会递归无止境intc;}

struct    SELF_REF1{inta;structSELF_REF1*b;//编译器在结构体的长度确定之前已经知道指针的长度,所以这种类型的自引用是合法的。链表就是这种技巧实现的fintc;}


作为函数参数的结构

结构变量是一个标量,它可以用于其他标量可以使用的任何场合。因此,把结构体作为参数传递给一个函数是合法的,但这种做法往往不适宜。

下面举一个例子

typedef struct{char  product[PRODUCT_SIZE];int    quantity;float  unit_price;float  total_amount;} Transaction;


print_receipt( Transation trans );   //这个是一个函数,参数是结构体    

警告:这个方法能够产生正确的结果,但它的效率很低,因为C语言的参数传值调用方式要求把参数的一份拷贝传递给函数。如果PRODUCT_SIZE为20,而且在我们使用的机器上整型和浮点型都占4个字节,那么这个结构体占据32个字节空间,要想把它作为参数进行传递,我们必须把32个字节复制到栈空间中,以后再丢弃。

print_receipt( Transation * trans );   //这个是一个函数,参数是结构体指针;

这次传递给函数的是一个指向结构的指针。指针比整个结构体小得多,所以把它压到堆栈上效率提高很多。传递指针另外需求=要付出的代价是我们必须在函数中使用间接访问来访问结构的成员。结构越大,把指向它的指针传递给函数的效率就越高。

在许多机器中,你可以把参数声明为寄存器变量,从而进一步提高指针传递方案的效率。在有些机器上,这种声明在函数的起始部分还需要一条额外的指令,用于把堆栈中的参数(参数先传递给堆栈)复制到寄存器,供函数使用。但是,如果函数对这个指针的间接访问次数超过两三次,那么使用这种方法所节省的时间将远远高于一条额外指令所花费的时间。

       向函数传递指针的缺陷在于函数现在可以对调用程序的结构体变量进行修改。如果我们不希望如此,可以在函数中使用const 关键字来防止这类修改。经过这两个修改之后,现在函数的原型将如下所示:

print_receipt( register  Transation  const * trans );  


0 0