小智-c语言

1.环境搭建

2.char&short&int

 

 3.if&switch

两种状态if,多种状态switch

开关灯if,网络状态switch

4.for&while

for比while代码更紧凑

5.static关键字

 初始化只在第一次做

6.const关键词

在C语言中,const是一个关键字,用于声明常量或指定变量为只读。它是C语言中的一种类型修饰符,用于表示一个值在程序执行期间不会被修改。一旦使用const关键字声明了一个常量或只读变量,其值就不能再被改变。

const关键字可以用在不同的上下文中:

  1. 声明常量:在C语言中,常量是不可修改的值。使用const关键字可以声明一个常量,并在声明时就初始化其值。例如:
const int MAX_VALUE = 100; 
const double PI = 3.1415926;
  1. 声明只读变量:在函数中,如果你想保护某个变量不被修改,你可以将其声明为只读变量。这样,如果在后续代码中尝试修改该变量的值,编译器会报错。例如:
void someFunction(const int x) { 
// 在这里,x是只读变量,你不能修改它的值
// x = 10; // 这样的赋值操作会导致编译错误
}
  1. 指向常量的指针:const关键字也可以用于指针类型,用来声明指向常量的指针。这意味着通过这个指针,你不能修改所指向的值,但可以修改指针本身。例如:
const int* ptr; // ptr是一个指向常量整数的指针,不能通过ptr修改所指向的值

或者

int const* ptr; // 与上面的声明等效,也是指向常量整数的指针
  1. 常量指针:const关键字还可以用于声明常量指针,这意味着不能通过指针修改所指向的地址,但可以修改所指向的值。例如:
int x = 5; int y = 10; int const *ptr = &x; // ptr是一个常量指针,不能通过ptr修改指向的地址 
*ptr = 7;
// 这样的赋值操作会导致编译错误
ptr = &y;
// 这是允许的,可以修改指向的地址

总之,const关键字在C语言中用于指定常量或只读变量,帮助编译器进行优化和提高代码的安全性。

7.define关键词

 define理解为替换

#define A (3+1)

确保头文件只被包含一次

在C语言中,#definetypedef是两个不同的关键词,用于定义符号和类型别名。

  1. #define:宏定义,用于创建文本替换。#define指令将一个标识符与一个文本片段关联起来,在编译之前进行简单的文本替换。例如:

    #define PI 3.14159
    int radius = 5;
    double circumference = 2 * PI * radius;
    

    在上面的例子中,#define定义了一个名为PI的宏,将其替换为3.14159。当编译器遇到PI时,会将其替换为3.14159,因此circumference变量的初始值将是31.4159

    宏定义可以用于定义常量、函数、条件编译等。

  2. typedef:类型定义,用于创建类型别名。typedef关键词可以给已存在的类型起一个新的名字。这对于简化复杂的类型声明很有用,提高了代码的可读性。例如:

    typedef int MyInt;
    MyInt x = 5;
    

    在上面的例子中,typedefint类型定义为MyInt,然后我们可以使用MyInt作为int类型的替代。这样做可以使代码更加清晰易读。

         综而言之,#define用于创建符号常量和简单的文本替换,而typedef用于创建类型别名,提高代码可读性。

8.enum关键字

enum代表枚举,默认情况下,枚举的第一个常量的值为0,后续常量的值逐个递增

9.struct关键字

10.指针

对于场景一,用变量传递只会改变形参,并不改变实参;而指针传递,会改变实际地址存储的数据;

对于场景二,用数组存着钥匙,用指针指向钥匙地址。

11.回调函数

在C语言中,回调函数是指将一个函数作为参数传递给另一个函数,并在后者的执行过程中被调用的函数。回调函数在很多情况下非常有用,例如事件处理、异步编程、接口实现等。通过使用回调函数,我们可以实现程序的灵活性和可扩展性。

以下是使用回调函数的一般步骤:

1. 定义回调函数:首先,你需要定义一个回调函数,其函数签名(参数列表和返回类型)需要与接收回调函数的函数所期望的一致。例如,假设我们要定义一个回调函数用于处理一个事件:

void callbackFunction(int event);

2. 声明接收回调函数的函数:在接收回调函数的函数中,你需要声明一个参数为函数指针的形参,用于接收回调函数。例如:

void someFunction(void (*callback)(int));

3. 在调用函数时传递回调函数:当你调用接收回调函数的函数时,可以将定义好的回调函数作为参数传递给它。例如:

someFunction(callbackFunction);

4. 在接收回调函数的函数中调用回调函数:在接收回调函数的函数内部,你可以通过函数指针调用传递的回调函数。例如:

void someFunction(void (*callback)(int)) {
// 执行一些操作...
int event = 10;
callback(event); // 调用回调函数
// 继续执行其他操作...
}

5. 实现回调函数:最后,你需要实现回调函数的功能,以便在调用时执行相应的操作。例如:

void callbackFunction(int event) {
// 执行回调函数的操作,根据传入的事件进行处理
printf("Received event: %d\n", event);
// 可以根据需要进行其他操作...
}

通过这样的方式,你可以将特定的功能委托给回调函数,以便在需要的时候进行调用。

需要注意的是,在使用回调函数时,函数指针的类型和参数列表需要匹配,否则会导致类型错误或未定义行为。另外,确保回调函数在被调用时是可用的,即回调函数的定义在调用之前。

12.数据拷贝

`malloc`函数在标准C库中用于动态分配内存。它在大多数操作系统和平台上提供了方便的内存分配和释放功能。然而,对于裸机编程(即在没有操作系统支持的嵌入式系统中编程),`malloc`函数并不被推荐使用,而应该避免或谨慎使用,原因如下:

1. 内存管理:`malloc`函数需要操作系统提供的内存管理功能支持,包括分配和释放内存的机制。在裸机环境中,没有操作系统,因此没有提供这些功能。这意味着无法使用标准的`malloc`和`free`函数来进行内存分配和释放。

2. 内存碎片:`malloc`函数在动态分配内存时可能导致内存碎片问题。当频繁进行内存分配和释放时,会产生不连续的内存块,造成内存碎片化。在裸机环境中,由于没有操作系统的内存管理功能,无法进行自动的内存整理和碎片清理。

3. 可移植性:`malloc`函数的实现方式和行为可能因平台和编译器而异。在裸机环境中,不同的嵌入式系统可能没有标准的`malloc`实现或具有不同的实现方式。这使得使用`malloc`函数的代码在不同的嵌入式平台上不可移植。

4. 预测性能:在裸机编程中,对性能和内存的控制通常是至关重要的。使用`malloc`函数会引入额外的开销,包括内存管理和错误处理的开销。这可能会导致不可预测的性能影响和额外的资源消耗。

在裸机编程中,更常见的做法是通过静态分配或使用特定的内存管理方案来管理内存。静态分配是在编译时为变量分配固定大小的内存空间,而特定的内存管理方案可以针对具体的嵌入式平台提供更好的性能和资源管理。

如果在裸机环境中需要动态分配内存,可以考虑使用特定于平台的内存分配函数或实现自己的内存管理机制,以满足特定的需求。这样可以更好地控制内存使用和提高代码的可移植性与可预测性。

13.实战框架

打印日志:

13.1  google测试框架

va_list   :表示可变参数列表类型

 

13.2  zlog日志框架

 

posted @ 2023-07-02 15:56  藍桉ouo  阅读(52)  评论(0)    收藏  举报