更好的使用结构体

结构体与指针

在C语言中,指针可以指向万物,自然也少不了结构体。

使用结构体指针,有4点好处:

  • 就像指向数组的指针比数组本身更容易操控一样,指向结构的指针通常比结构本身更容易操控
  • 在早期的C中,结构不能作为参数传递给函数,但是可以传递指向结构的指针
  • 即使能传递一个结构,传递指针通常更有效率
  • 一些用于表示数据的结构中包含指向其他结构的指针

根据这4点好处,证明学习结构体指针的重要性

// Book结构体沿用上面
int main(void) {
    struct Book books[2] = {
        {"C Primer Plus", "Stephen Prata", 59.4},
        {"黑客与画家", "Paul Graham", 49.00}
    };
    
    struct Book * book1; // 这是一个指向结构的指针
    book1 = &books[0]; // 告诉编译器指针指向何处:结构数组第一个结构
    
    printf("[book1] title = %s, author = %s, price = %f\n", book1->title, book1->author, book1->price);
    
    book1++;
    
    printf("[book1] title = %s, author = %s, price = %f", book1->title, book1->author, book1->price);
	return 0;
}

Output:
[book1] title = C Primer Plus, author = Setphen Prata, price = 59.4
[book1] title = 黑客与画家, author = Paul Graham, price = 49

声明和初始化结构指针

声明结构指针很简单:

struct Book * book;

首先是关键字struct,其次就是结构标记Book,然后星号(*)代表着指针,跟着指针名。语法与其他指针声明一样。

该声明并未创建一个新的结构,但是指针book现在可以指向任意现有的Book类型的结构。例如,如果book1是一个Book类型的结构,那么就可以这样写:

book = &book1;

使用指针访问结构成员

使用指针访问结构成员有两种方法。

第一种也是最常用的一种就是使用 -> 运算符,该运算符由一个连接号 ( - ) 后跟一个大于号 ( > ) 组成

第二种方法就是老套的指针取值,使用*获取结构成员的值

printf("Book's title = %s\n", book->title);
printf("Book's title = %s\n", (*book).title);

向函数传递结构信息

函数的参数把值传递给函数,每个值都是一个数字----可能是int类型、float类型,可能是ASCII字符码,或者是一个地址。然而,一个结构比一个单独的值复杂,所以较早时期的C实现不允许把结构作为参数传递给函数。当前的实现已经移除了这个限制,C允许把结构作为参数使用。所以可以选择是传递结构本身,还是传递指向结构的指针。

传递结构成员

struct Book {
	char title[128];
	char author[40];
	float price;
}
void output(char title[], float price);
int main(void) {
	struct Book book = {"C Primer Plus", "Stephen Prata", 59.4};
	output(book.title, book.price);
	return 0;
}
void output(char title[], float price) {
	printf("书名: 《%s》, 价格: %f\n", title, price);
}

传递参数没问题,因为output()函数即不知道也不关心实际的参数是否是结构的成员,它只要求被传入的数据是char数组和float类型。
如果想要再被调函数中修改主调函数中成员的值,就要传递成员的地址。

传递结构的地址

struct Formula {
	int a;
	int b;
}
int sum(struct Formula *); // 参数是一个指针
int main(void) {
	struct Formula formula = {1, 2};
	int result = sum(&formula);
	return 0;
}
int sum(struct Formula * formula) {
	return (formula->a + formula->b);
}

传递结构

struct Formula {
	int a;
	int b;
}
int sum(struct Formula);
int main(void) {
	struct Formula formula = {1, 2};
	int result = sum(formula);
	return 0;
}
int sum(struct Formula form) {
	return (form.a + form.b);
}

调用sum()时,编译器根据Formula模板创建了一个名为form的自动结构变量。然后,该结构的各成员被初始化为formula结构变量相应成员的值的副本。因此,程序使用原来结构的副本进行计算,然而,传递指针的程序使用的是原始的结构进行计算。由于form是另一个结构,所以该程序使用form.a,而不是form->a。

# C 
樱花正含苞待放,春天就要来了🌸
标题:更好的使用结构体
作者:bogendihong
地址:https://myjinji.top/articles/2020/11/15/1605603446789.html

评论

取消