结构基础知识
C的聚合数据类型(aggregate data type) 能够同时存储超过一个的单独数据.
C提供了两种类型的聚合数据类型,数组和结构.
- 数组是相同类型的元素的集合,它的每个元素是通过下标引用或指针间接访问来选择的.
- 结构也是一些值的集合,值成为它的成员(member),结构属于标量类型可以作为传递给函数的参数,它们也可以作为返回值从函数返回,相同类型的结构变量之间可以赋值,可以声明指向结构的指针,取一个结构变量的地址,也可以声明结构数组.
一些结构体的使用误区
struct
{
int a;
char b;
float c;
}
struct
{
int a;
char b;
float c;
}y[20], *z;
z = &x;//此语句是非法的使用
这两个声明被编译器当做两种不同的类型,即是它们的成员列表完全相同.因此,变量y和z的类型和x的类型不同, z = &x语句是非法的
两种不同函数参数定义的函数
定义结构体,仿照int求和函数
#include <stdio.h>
//定义复数结构体,类型重命名为complex
typedef struct
{
int real;
int imaginary;
}complex;
/*
** 类比整型的求和函数
** int sum(int a, int b);
** 函数返回值是结构体,函数参数也是结构体类型
*/
complex Sum_Complex(complex a, complex b)
{
complex temp;
temp.real = a.real + b.real;
temp.imaginary = a.imaginary + b.imaginary;
return temp; //返回结构体
}
int main()
{
complex a1, a2, sum;
printf("Please input the first number's real part and imaginary part:\n");
scanf("%d %d", &a1.real, &a1.imaginary);
printf("Please input the second number's real part and imaginary part:\n");
scanf("%d %d", &a2.real, &a2.imaginary);
sum = Sum_Complex(a1, a2);
//结构体变量访问成员方式
printf("Sum is %d + %di\n", sum.real, sum.imaginary);
}
这个函数虽然能够产生正确地结果,但是效率很低.
C语言的参数传值调用方式要求把参数的一份拷贝传递给函数,要想把它作为参数进行传递,必须在堆栈中进行复制,结束后再丢弃,利用效率非常低.
利用结构体 指针重新编写
#include <stdio.h>
#include <stdlib.h>
//定义复数结构体,类型重命名为complex
typedef struct
{
int real;
int imaginary;
}complex;
//返回值:complex的结构体指针
//函数参数也是结构体指针
complex *Add(complex *x, complex *y)
{
//malloc返回值是一个指针,不能申(complex)malloc(sizeof(complex))
complex *result = (complex *)malloc(sizeof(complex));
result->real = x->real + y->real;
result->imaginary = x->imaginary + y->imaginary;
return result; //返回结构体
}
//亮点:将打印写成函数
void Print_Struct(complex * ps)
{
printf("%d + %di", ps->real, ps->imaginary);
}
int main()
{
//结构体成员赋值可以用括号
complex a1 = {1, 2};
complex a2 = {3, 4};
//定义结构体指针
complex *result = Add(&a1, &a2);//&a1, &a2指针
Print_Struct(result);
return 0;
}
利用指针进行传递显然好的多
- 它并不需要把整个结构作为参数传递给函数,也不需要把整个结构作为返回值返回
- 调用程序无需知道结构的内容,所以提高了程序的模块化程度.
- PS:函数传递指针的缺陷在于函数可以对调用程序的结构变量进行修改.可以在函数中使用const关键字来防止这类修改