|
我是老温,一名热爱学习的嵌入式工程师
( 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
( 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
; 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
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
关注我,一起变得更加优秀! |
|