电子产业一站式赋能平台

PCB联盟网

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

嵌入式 C 语言,那些“花里胡哨”的语法特性。

[复制链接]

485

主题

485

帖子

1623

积分

三级会员

Rank: 3Rank: 3

积分
1623
发表于 2024-8-20 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
( q9 g, n' h& _关注我,一起变得更加优秀!% s' [, q4 u6 A
在嵌入式软件开发领域,C 语言是一种功能强大、灵活的编程语言,它提供了很多语法特性,有些语法可能看起来比较"花里胡哨",用得好可能利大于弊,用不好,可能就是自己给自己挖坑。
# h2 m8 C/ C! h: B8 F以下是一些可能被认为花哨的C语言特性及其示例:- _# I) a% y+ P+ V  U  i
1. 宏定义的高级用法
$ e4 m. I. J. {4 g* ~使用宏可以模拟函数的行为,但要注意宏的副作用和调试难度。
  • #define SQUARE(x) ((x) * (x))int a = 5;printf("%d9 ^* X# X$ L4 ^- S7 Z" B
    ", SQUARE(a++)); // 输出25,但a的值会改变为6" `" F+ D' v- [! M# o( L
    2. 指针的指针
    - H9 G* H9 [1 d4 B: J指向指针的指针可以用于实现复杂的数据结构,比如二维数组。
  • int **pptr;int arr[2][2] = {{1, 2}, {3, 4}};pptr = &arr[0];printf("%d
    " }; W' @9 ]' J/ Z8 g2 w", *(*(pptr + 1) + 1)); // 输出4- a. [  V8 K: w% Y" R- p
    3. 函数指针数组
    % l0 Q& X: B6 e9 R) U$ C" K数组中的每个元素都是指向函数的指针,这可以用于回调函数或实现简单的函数映射。
  • void (*func_array[])(int) = {func1, func2, func3};func_array[1](42); // 调用func2
    ; [3 _8 u2 J( X- U# N% t, S" m4. 结构体和联合体作为函数参数- X# P" ]3 v/ j0 q7 L. k5 }) s
    使用结构体或联合体作为函数参数可以传递复杂的数据结构。
  • struct Point {     int x, y;};
    3 ?4 ^/ Z! I0 Mvoid print_point(struct Point p) {   printf("(%d, %d)
    + c0 T1 u( j; n7 `) c( u- b", p.x, p.y);}( x% e$ }( I) f- e: L+ ?' U* [
    struct Point p = {1, 2};print_point(p);, n% Z% Q; v. s
    5. 静态和动态内存分配: s) a  }9 u- D6 P) W
    使用 “malloc” 和 “free” 可以动态地分配和释放内存。
  • int *p = malloc(sizeof(int) * 10);
    7 u: D- F! K/ S4 V& Wif (p) {  for (int i = 0; i 10; i++) {    p = i * i;  }  free(p);}+ ~2 c6 ~7 A5 v: _
    6. 复杂的递归
    * M# G9 F: a2 E递归函数可以用于解决分治问题,但需要小心处理避免栈溢出。
  • int factorial(int n){    if (n 1) return 1;    return n * factorial(n - 1);}
    3 c: J. a9 @9 x7 d5 r  ]7. 位操作
    * d9 w$ U, P( N% L4 j/ O# e- v/ P位操作可以用于设置、清除、翻转、测试位的状态。
  • int flags = 0x03; // 00000011flags |= 0x04;    // 00000101flags &= 0x01;    // 00000001flags ^= 0x01;    // 11111110# [: X; C5 ]' v
    8. 复杂的条件编译
      s9 i2 \4 L- }$ V5 D6 _预处理器的"#if"、"#ifdef"、"#ifndef"、"#elif"、"#else"和"#endif"指令可以用于复杂的条件编译。
  • #define DEBUG 1 int main() {     #if DEBUG     printf("Debug mode is on.
    + n9 W# o  U) K3 P  u9 L");     #endif     #ifdef DEBUG     // 调试代码     #endif     return 0; }4 q; a- \/ T" w. P, r7 n0 _8 X. I* j
    9. 复杂的类型转换! n8 q  z9 Q* \1 [+ R/ V
    强制类型转换可以用于将一种类型的数据转换为另一种类型,但需要小心使用以避免问题。
  • double d = 3.14159;int *p = (int *)&d;printf("%d4 \6 S' T( W0 r6 E
    ", *p); // 输出整数部分,可能不安全
    9 S* U. V5 o1 k. u; c10. 使用"__attribute__"扩展' S- J# C8 \5 t3 ^! H, H8 P; G
    "__attribute__"是GCC编译器提供的扩展,可以用来控制函数的调用约定、内联等。
  • void __attribute__((noreturn)) fatal_error(const char *msg) {    fprintf(stderr, "Fatal error: %s
      C6 U$ h" V0 S# T" x: L", msg);    exit(EXIT_FAILURE);}9 k* U# _5 S/ }7 B" H, c
    这些特性在某些情况下非常有用,但它们也可能使代码难以理解和维护。因此,在使用这些特性时,应该权衡其利弊,并确保代码的清晰性和可读性。
    * I  d: x2 X) r" T-END-* F9 R5 N( g! i* R8 N' o1 X7 C
    往期推荐:点击图片即可跳转阅读
    " o0 ~6 I4 I& q6 L

    4 e2 E( Y; m+ Y, ]                                                       
    ' r# R) J, Z, n3 `$ {% y: j/ k                                                                9 S3 |9 ~* }# g( o5 J
                                                                            5 X4 U6 C8 e- J: w/ |2 g0 Q0 w
                                                                                    % d- B6 a4 F- z$ u# d5 s" g- A) h3 p

    wej3wtbzhu164020400711.jpg

    wej3wtbzhu164020400711.jpg
    ( e  N9 X+ ]- n* S; O8 s8 Y0 R
                                                                                   
    ( Y. X  v4 @) t8 T- N                                                                                        被 char 类型的变量坑惨了!( {. \) U. }7 k+ b6 B
                                                            3 F( O0 Y! ^( n3 u9 Z- z! w
                                                                    , ]3 R& n3 p. K. Q- {- B2 ^* i6 N
                                                                           
    ) W+ M1 q, P0 O3 k* w* o                                                                               
    2 f' u9 ~( F  {7 m; j& ?0 g3 b

    vixd04kipy464020400811.jpg

    vixd04kipy464020400811.jpg

    ; A0 e) I# h! ^5 B0 s+ W& P/ J                                                                                5 s* b# E: F1 j2 V" W- e
                                                                                            嵌入式 C 语言知识点,动态变长数组
    ( I( e8 @& w; g0 b& i2 x! H& W                                                        . u+ S$ `0 e, c& o
                                                                   
    9 A4 T0 g5 a* c' o+ a6 _                                                                        $ V3 v9 y" Q5 }
                                                                                   
      u' t  t) b, y$ R4 c6 v

    k0ypsqhklps64020400911.jpg

    k0ypsqhklps64020400911.jpg
      H! N0 m; c- r  w
                                                                                   
    ( D2 u2 g) q' X                                                                                        嵌入式 C 语言技巧,不完全类型
    9 E/ k( L4 Y( z0 O我是老温,一名热爱学习的嵌入式工程师) E& j' `, l8 {0 W$ c. M6 R
    关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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