结构变量是一个标量,它可以用于其他标量可以使用的任何场合,但把结构体作为参数传递给一个函数要注重效率
例如下面这样一个结构体:
#define PRODUCT_SIZE 20
typedef struct{
char product[PRODUCT_SIZE];
int quantity;
float unit_price;
float total_amount;
}Transaction;
如果我们需要打印里面的数据,函数原型为:
void print_receipt(Transaction trans);
将结构体直接传递到函数参数,这样结果正确,但是效率很低,因为C语言的参数传递调用方式要求把参数的一份拷贝传递给函数,我们知道这个结构体占据32个字节的内存空间,要想把它作为参数进行传递,我们必须把32个字节复制到堆栈中,以后再丢弃,但如果传递的是指针:
void print_receipt(Transaction *trans);
传递的参数是一个指向结构体的指针,指针比结构体小得多,所以把它压到堆栈上效率要提高很多,传递指针的代价是我们必须在函数中使用间接访问来访问结构的成员,结构越大,把它指向它的指针传递给函数的效率越高。
向函数传递指针的缺陷在于函数现在可以调用程序的结构变量进行修改,如果我们不希望如此,可以在函数调用中使用关键字const来防止这类修改。
void print_receipt(Transaction const *trans);
另外,需要对结构体里面的变量进行修改,传递指针也是效率最高的一种:
//效率最低,结构体的一份拷贝作为参数传递给函数并被修改,然后一份修改后的结构拷贝从函数返回,结构体被复制了两次
Transaction compute_total_Transaction(Transaction trans)
{
trans.total_amount = trans.quantity * trans.unit_price;
return trans;
}
//结构体被复制了一次
float compute_total_Transaction(Transaction trans)
{
return trans.quantity * trans.unit_price;
}
//效率最高,调用程序的结构字段total_amount被直接修改,它并不需要把整个结构作为参数传递给函数,也不需要把整个修改过后的结构作为返回值返回;
void compute_total_Transaction(Transaction *trans)
{
trans->total_amount = trans->quantity * trans->unit_price;
}