|

星标+置顶,掌握嵌入式AIoT前沿技术资讯
( z& E: ?, J! E" b点赞+关注,一起变得更加优秀!
5 W2 T9 U* U6 a5 z5 g在C语言中,结构体是一种非常强大的数据类型,可以用来组织和存储复杂的数据。本文将详细介绍如何将结构体及其成员传递给函数,并探讨相关的特性与注意事项。
$ l7 B, p4 P/ M1. 传递结构体成员4 N) X* h& h/ P0 z
如果结构体的某个成员是基本数据类型(如int、double、char等),可以直接将该成员作为参数传递给函数。
. _; i8 y. g" l0 {# u以下是一个简单的示例,展示了如何将结构体的成员传递给函数进行计算:#include #define FUNDLEN 50
4 Y4 j3 M' I7 }& i9 G; c/ }0 G% Gstruct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};
+ R4 C! m6 p0 F1 Y+ r/ K" F" @double sum(double, double);
1 W2 t, Z$ p! y# S9 y$ ^7 l" O' f/ _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.# F/ e, m( c9 R7 O% I8 [' d
", sum(stan.bankfund, stan.savefund)); return 0;}
) `" M7 ?/ T& X( v/ Bdouble sum(double x, double y) { return x + y;}输出:Stan has a total of $12576.21.这里,sum()函数并不关心参数是否来自结构体,它只关心传入的参数是double类型。8 H- w, J% C6 C3 z: i, h4 p
注意:如果需要在函数中修改结构体成员的值,则需要传递成员的地址。
% G3 k3 [* o9 h2. 传递结构体的地址
R! C, {, P& C" R: q% K$ z: C当需要在函数中访问或修改整个结构体的数据时,可以将结构体的地址传递给函数。这种方式效率高,且避免了数据的复制。#include #define FUNDLEN 50: p5 S4 h6 y D' c
struct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(const struct funds *);
/ @4 [3 L3 ~2 q+ V/ _+ zint main(void) { struct funds stan = { "Garlic-Melon Bank", 4032.27, "Lucky's Savings and Loan", 8543.94 }; printf("Stan has a total of $%.2f.
6 n% y' v& b |6 P( R) Q", sum(&stan)); return 0;}
% Z) S. y/ t; g, a& [, O. i; n/ sdouble sum(const struct funds *money) { return money->bankfund + money->savefund;}这里,sum()函数通过指针money访问结构体的成员。->运算符用于访问指针指向的结构体成员。+ T1 J! s4 X# I, |4 [
注意:使用const修饰指针可以避免意外修改原始数据。
* R/ [8 } `5 \8 v; q3. 传递整个结构体
8 X" m6 K3 i. c& ^- Q+ h1 a也可以将整个结构体作为参数传递给函数。这种方式会创建结构体的一个副本,因此不会影响原始数据。#include #define FUNDLEN 50# d- t5 [3 h) n$ l! q) c
struct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(struct funds);9 K# @1 L7 g& P9 Y0 @
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.
7 K0 a2 r! X$ v2 s", sum(stan)); return 0;}; a/ s! r9 n/ a9 k9 z; K- R
double sum(struct funds moolah) { return moolah.bankfund + moolah.savefund;}这里,sum()函数接收一个结构体副本,并通过 . 运算符访问其成员。# M" S* x4 k4 }7 ^ {2 U$ r& Z& A
4. 结构体的其他特性
2 L+ i- u0 k+ y4.1 结构体赋值1 q* q' K+ i* Y. Y3 o1 a. ~
C语言允许将一个结构体赋值给另一个相同类型的结构体。例如:struct names { char first[20]; char last[20];};struct names a = {"Alice", "Smith"};struct names b = a; // 将a的值赋给b4.2 结构体作为返回值+ l- s( i0 _- W$ s! t
函数可以返回一个结构体。例如: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 结构体参数
8 t2 k+ n& ]+ N8 @/ {结构体指针:传递效率高,但需要小心保护原始数据。结构体参数:传递的是副本,安全性更高,但可能增加内存开销。
1 H/ q8 q5 t. w V% W+ c7 d' ^5. 结构体中的字符数组与指针7 k5 t* ]( t$ R+ C: N: W
在结构体中,可以使用字符数组或指针来存储字符串。以下是两种方式的对比:7 e. x1 p' |% N
5.1 字符数组struct names { char first[20]; char last[20];};字符串存储在结构体内部,安全性高,但占用固定大小的内存。! o. @ I7 [3 |' r% W
5.2 指针struct pnames { char *first; char *last;};字符串存储在其他内存区域,结构体中只存储地址。这种方式更灵活,但需要小心内存管理。
: ]- ~" U$ Z) O注意:使用指针时,需避免未初始化的指针导致的潜在问题。
, u& c, n; k. M7 J6. 动态内存分配与结构体
2 {9 O* p( r# j7 w# Y使用malloc()动态分配内存可以灵活管理字符串存储。例如:struct namect { char *fname; char *lname; int letters;};
5 p2 f) h1 ^, t* V- j6 |% Dvoid 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);}
6 B N) R9 d% y/ F+ X7 ^void cleanup(struct namect *pst) { free(pst->fname); free(pst->lname);}注意:动态分配的内存需要通过 free() 释放,避免内存泄漏。; ~/ w, B) @! u+ `
7. 结构体数组与函数
5 s9 W7 e- |$ k5 Q0 ^可以将结构体数组传递给函数,函数通过指针访问数组中的元素。例如:#include #define FUNDLEN 50#define N 2
6 j* k/ M5 v _; h1 ?( v' ?! z+ l: cstruct funds { char bank[FUNDLEN]; double bankfund; char save[FUNDLEN]; double savefund;};double sum(const struct funds money[], int n);, Z4 G, Y& z1 R' p8 @' D
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.
; s7 [8 }" D* \1 h% s8 U) B", sum(jones, N)); return 0;}4 S* M3 t1 R! u. | ^' o1 K. v
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.注意:数组名作为参数传递时,实际上是传递了数组首元素的地址。, l/ ]/ D* ~/ L6 C6 [+ k+ `
-END-
+ M. s8 L6 i$ B* J往期推荐:点击图片即可跳转阅读
?* z: q& d; r' `
3 @ D) `# {8 N% u7 L% A1 K9 N
zeoeeip3vro6409000116.jpg
7 _2 S9 l1 [, r% p, H6 a" m
嵌入式开发者的效率神器:Serial-Studio实战解析!# m2 @$ x9 |6 T' Q% b
suxveeofs016409000216.jpg
C" q0 e, p9 O$ z: U1 `6 t2 R" {
嵌入式软件工程师,凌晨三点还在Debug,没想到故障竟然是。。。- s+ m9 k; U+ a) K9 m8 r
pqcwocsueiq6409000316.jpg
% v# X2 O2 Y0 D+ r2 b1 K" c1 B" a$ r( Z3 Y科普嵌入式相关概念, CPU、MCU、MPU、SOC、MCM、NPU,分别代表什么?9 I% _* T; y7 u4 U) X5 N) `
星标+置顶,掌握嵌入式AIoT前沿技术资讯
+ u" }- |: w/ N6 O. f点赞+关注,一起变得更加优秀! |
|