电子产业一站式赋能平台

PCB联盟网

搜索
查看: 53|回复: 0
收起左侧

嵌入式 C 语言基础知识,如何向函数内部传递结构信息?

[复制链接]

561

主题

561

帖子

3987

积分

四级会员

Rank: 4

积分
3987
发表于 3 天前 | 显示全部楼层 |阅读模式
星标+置顶,掌握嵌入式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

    zeoeeip3vro6409000116.jpg

    # g0 M* Y2 y% ?2 ^7 i* H嵌入式开发者的效率神器:Serial-Studio实战解析!# d, @1 f- w4 `7 ]6 D5 O" R

    suxveeofs016409000216.jpg

    suxveeofs016409000216.jpg
    6 G3 u2 y7 Q6 I) [4 p* \
    嵌入式软件工程师,凌晨三点还在Debug,没想到故障竟然是。。。8 ?4 Z. g- c# m0 `& A3 C

    pqcwocsueiq6409000316.jpg

    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
    点赞+关注,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表