|
星标+置顶,掌握嵌入式AIoT前沿技术资讯0 h: c' D6 H/ M5 r5 c8 {
点赞+关注,一起变得更加优秀!
$ Y2 j6 x$ F+ V, g+ R在C语言中,结构体是一种非常强大的数据类型,可以用来组织和存储复杂的数据。本文将详细介绍如何将结构体及其成员传递给函数,并探讨相关的特性与注意事项。
5 l, v n' F6 C; \3 J' r! X- \1 ]1. 传递结构体成员" v% R8 o7 E4 @6 N, e2 r
如果结构体的某个成员是基本数据类型(如int、double、char等),可以直接将该成员作为参数传递给函数。
6 E' X4 F' `( A* k7 m以下是一个简单的示例,展示了如何将结构体的成员传递给函数进行计算:#include #define FUNDLEN 50% { U" ?/ S3 h6 T& l- P. F
struct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};
* N0 W3 m! k4 f; E! J* jdouble sum(double, double);* b! r1 P, Y! s5 }7 |
int main(void) { struct funds stan = { "Garlic-Melon Bank", 4032.27, "Lucky's Savings and Loan", 8543.94 }; printf("Stan has a total of $%.2f.3 |2 [& m7 v" F8 t
", sum(stan.bankfund, stan.savefund)); return 0;}
. @! z, s# z8 ]+ S; tdouble sum(double x, double y) { return x + y;}输出:Stan has a total of $12576.21.这里,sum()函数并不关心参数是否来自结构体,它只关心传入的参数是double类型。
/ a) f7 Q5 q5 K, p9 w; {注意:如果需要在函数中修改结构体成员的值,则需要传递成员的地址。: t- I0 x- e$ o7 ]
2. 传递结构体的地址: o* e; |+ I* \; W/ ~
当需要在函数中访问或修改整个结构体的数据时,可以将结构体的地址传递给函数。这种方式效率高,且避免了数据的复制。#include #define FUNDLEN 506 [! h2 f5 G( ?8 O$ J2 ?! D
struct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(const struct funds *);
& [! g' N) Q6 ^int main(void) { struct funds stan = { "Garlic-Melon Bank", 4032.27, "Lucky's Savings and Loan", 8543.94 }; printf("Stan has a total of $%.2f.
4 p# }/ O' c" T& O) n0 P", sum(&stan)); return 0;}
) N% w& O- Z+ ?8 P" ~8 ^' k; Pdouble sum(const struct funds *money) { return money->bankfund + money->savefund;}这里,sum()函数通过指针money访问结构体的成员。->运算符用于访问指针指向的结构体成员。
2 V3 c8 j/ ?; [5 F( E注意:使用const修饰指针可以避免意外修改原始数据。
; }1 U2 ]! b ~, U; a6 [6 I3. 传递整个结构体
0 k! e/ A8 ^4 T) m8 H W也可以将整个结构体作为参数传递给函数。这种方式会创建结构体的一个副本,因此不会影响原始数据。#include #define FUNDLEN 503 K9 `$ j: m8 H" Z/ I6 k
struct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(struct funds);+ L1 j! q: j3 g1 \6 |4 `0 B
int main(void) { struct funds stan = { "Garlic-Melon Bank", 4032.27, "Lucky's Savings and Loan", 8543.94 }; printf("Stan has a total of $%.2f.0 n i! U1 e* [; D7 S+ V. ?! E
", sum(stan)); return 0;}
- f& G8 u0 B/ R% pdouble sum(struct funds moolah) { return moolah.bankfund + moolah.savefund;}这里,sum()函数接收一个结构体副本,并通过 . 运算符访问其成员。
5 |3 ~+ a! H* D0 l4. 结构体的其他特性
1 Q# E* m/ U$ p2 I8 a8 \4.1 结构体赋值
& K* ?% k' Q( q$ r3 F! fC语言允许将一个结构体赋值给另一个相同类型的结构体。例如:struct names { char first[20]; char last[20];};struct names a = {"Alice", "Smith"};struct names b = a; // 将a的值赋给b4.2 结构体作为返回值
: X0 Z/ Z: F2 A, g- d# x8 B函数可以返回一个结构体。例如:struct vector { double x; double y;};struct vector sum_vect(struct vector a, struct vector b) { struct vector result; result.x = a.x + b.x; result.y = a.y + b.y; return result;}4.3 结构体指针 vs 结构体参数
! p" P J3 S# ^* O) h P5 E结构体指针:传递效率高,但需要小心保护原始数据。结构体参数:传递的是副本,安全性更高,但可能增加内存开销。4 W4 O9 @. X- B$ L
5. 结构体中的字符数组与指针
/ ]( q" q+ `6 E3 l4 F% [1 l在结构体中,可以使用字符数组或指针来存储字符串。以下是两种方式的对比:
% @$ ?( C: R) q. f: O8 i5.1 字符数组struct names { char first[20]; char last[20];};字符串存储在结构体内部,安全性高,但占用固定大小的内存。$ l0 H5 W1 u& l5 w6 y% k
5.2 指针struct pnames { char *first; char *last;};字符串存储在其他内存区域,结构体中只存储地址。这种方式更灵活,但需要小心内存管理。, U8 c$ q- c/ K, W) [; r- ]7 M
注意:使用指针时,需避免未初始化的指针导致的潜在问题。* t$ g+ F6 ~: f5 v
6. 动态内存分配与结构体
' k: a0 b6 |1 l$ W. I. A使用malloc()动态分配内存可以灵活管理字符串存储。例如:struct namect { char *fname; char *lname; int letters;};' j6 F* o: w9 I; q- n7 f4 M. I, {
void getinfo(struct namect *pst) { char temp[50]; printf("Enter first name: "); scanf("%s", temp); pst->fname = (char *)malloc(strlen(temp) + 1); strcpy(pst->fname, temp); printf("Enter last name: "); scanf("%s", temp); pst->lname = (char *)malloc(strlen(temp) + 1); strcpy(pst->lname, temp);}# c" @2 P$ a1 n8 N3 }! W4 W, l
void cleanup(struct namect *pst) { free(pst->fname); free(pst->lname);}注意:动态分配的内存需要通过 free() 释放,避免内存泄漏。
7 n" Z# h0 ]! B+ w! H( |8 y( y+ C7. 结构体数组与函数& _- S4 k3 @2 D" j
可以将结构体数组传递给函数,函数通过指针访问数组中的元素。例如:#include #define FUNDLEN 50#define N 2
, E* ~+ _) M" Y- X. V( Ystruct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(const struct funds money[], int n);
; b' x7 x |/ c' ~int main(void) { struct funds jones[N] = { {"Garlic-Melon Bank", 4032.27, "Lucky's Savings and Loan", 8543.94}, {"Honest Jack's Bank", 3620.88, "Party Time Savings", 3802.91} }; printf("The Joneses have a total of $%.2f.9 U4 t6 U$ W2 `% L( `
", sum(jones, N)); return 0;}+ ~: Z8 q+ M! J4 Q$ {( }0 F! `
double sum(const struct funds money[], int n) { double total = 0; for (int i = 0; i total += money.bankfund + money.savefund; } return total;}输出:The Joneses have a total of $20000.00.注意:数组名作为参数传递时,实际上是传递了数组首元素的地址。
; T( t# i7 I& C6 x! k-END-, [" g$ Z. v& a( K8 o
往期推荐:点击图片即可跳转阅读
# F2 j& ~: ~( ~" H) M( j$ _6 Y- Q9 I$ s \
zeoeeip3vro6409000116.jpg
# g0 M* Y2 y% ?2 ^7 i* H嵌入式开发者的效率神器:Serial-Studio实战解析!# d, @1 f- w4 `7 ]6 D5 O" R
suxveeofs016409000216.jpg
6 G3 u2 y7 Q6 I) [4 p* \
嵌入式软件工程师,凌晨三点还在Debug,没想到故障竟然是。。。8 ?4 Z. g- c# m0 `& A3 C
pqcwocsueiq6409000316.jpg
q, S# j1 Z. e) K$ N' N, |科普嵌入式相关概念, CPU、MCU、MPU、SOC、MCM、NPU,分别代表什么?' L# [6 m( |1 ], T
星标+置顶,掌握嵌入式AIoT前沿技术资讯+ a9 t0 d/ D, `2 Q* D
点赞+关注,一起变得更加优秀! |
|