C语言常见概念

1. 内存管理

示例:动态分配和释放二维数组

#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows = 3, cols = 4;
    // 动态分配二维数组
    int **array = (int **)malloc(rows * sizeof(int *));
    if (array == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    for (int i = 0; i < rows; i++) {
        array[i] = (int *)malloc(cols * sizeof(int));
        if (array[i] == NULL) {
            perror("Failed to allocate memory");
            // 释放已分配的内存
            for (int j = 0; j < i; j++) {
                free(array[j]);
            }
            free(array);
            return 1;
        }
    }

    // 初始化并打印数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            array[i][j] = i * cols + j;
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }

    // 释放内存
    for (int i = 0; i < rows; i++) {
        free(array[i]);
    }
    free(array);

    return 0;
}

解释:

  • 使用 malloc 动态分配内存来创建一个二维数组。
  • 检查每次分配是否成功,避免内存泄漏。
  • 使用完毕后,使用 free 释放所有分配的内存。

2. 指针和多级指针

示例:使用多级指针修改变量的值

#include <stdio.h>

int main() {
    int value = 10;
    int *ptr = &value;
    int **ptr2 = &ptr;

    printf("Original value: %d\n", value); // 输出 10
    **ptr2 = 20;
    printf("Modified value: %d\n", value); // 输出 20

    return 0;
}

解释:

  • ptr 是指向 value 的指针。
  • ptr2 是指向 ptr 的指针(多级指针)。
  • 通过 **ptr2 修改 value 的值。

3. 指针运算

示例:指针与数组的关系

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr; // 数组名作为指针

    for (int i = 0; i < 5; i++) {
        printf("Element %d: %d\n", i, *(ptr + i));
    }

    return 0;
}

解释:

  • 数组名 arr 可以作为指针使用。
  • 通过指针运算 *(ptr + i) 访问数组元素。

4. 位操作

示例:设置、清除和切换位

#include <stdio.h>

int main() {
    unsigned int num = 0b0000; // 初始为 0

    // 设置第2位(从0开始计数)
    num |= (1 << 2);
    printf("After setting bit 2: %04b\n", num); // 输出 0100

    // 清除第2位
    num &= ~(1 << 2);
    printf("After clearing bit 2: %04b\n", num); // 输出 0000

    // 切换第1位
    num ^= (1 << 1);
    printf("After toggling bit 1: %04b\n", num); // 输出 0010

    return 0;
}

解释:

  • 使用位运算符 |, &, ^ 来设置、清除和切换特定位。
  • 1 << n 用于创建一个掩码,将第 n 位设为1。

5. 宏和预处理器

示例:使用宏定义和条件编译

#include <stdio.h>

#define PI 3.14159
#define SQUARE(x) ((x) * (x))

// 条件编译
#define DEBUG

int main() {
    double radius = 5.0;
    double area = PI * SQUARE(radius);
    printf("Area: %.2f\n", area);

#ifdef DEBUG
    printf("Debug Mode: radius=%.2f, area=%.2f\n", radius, area);
#endif

    return 0;
}

解释:

  • #define 用于定义常量和宏函数。
  • SQUARE(x) 计算 x 的平方。
  • 使用 #ifdef 进行条件编译,根据是否定义 DEBUG 来决定是否输出调试信息。

6. 函数指针

示例:使用函数指针实现回调

#include <stdio.h>

// 定义函数指针类型
typedef void (*Callback)(int);

// 一个接受回调函数的函数
void process(int data, Callback cb) {
    // 处理数据
    data += 10;
    // 调用回调函数
    cb(data);
}

// 回调函数
void myCallback(int result) {
    printf("Callback called with result: %d\n", result);
}

int main() {
    int value = 5;
    process(value, myCallback); // 传递回调函数
    return 0;
}

解释:

  • 定义一个函数指针类型 Callback,指向接受 int 参数且返回 void 的函数。
  • process 函数接受一个整数和一个回调函数指针,处理数据后调用回调。
  • main 中,将 myCallback 作为回调函数传递给 process

7. 复杂的结构体和联合体

示例:使用嵌套结构体和联合体

#include <stdio.h>
#include <string.h>

// 定义日期结构体
typedef struct {
    int year;
    int month;
    int day;
} Date;

// 定义人员结构体,包含联合体
typedef struct {
    char name[50];
    int age;
    Date birthdate;
    union {
        char studentID[20];
        char employeeID[20];
    } id;
    int isStudent; // 1 表示学生,0 表示员工
} Person;

int main() {
    Person p1;
    strcpy(p1.name, "Alice");
    p1.age = 25;
    p1.birthdate.year = 1998;
    p1.birthdate.month = 5;
    p1.birthdate.day = 15;
    p1.isStudent = 1;
    strcpy(p1.id.studentID, "S12345678");

    Person p2;
    strcpy(p2.name, "Bob");
    p2.age = 30;
    p2.birthdate.year = 1993;
    p2.birthdate.month = 8;
    p2.birthdate.day = 22;
    p2.isStudent = 0;
    strcpy(p2.id.employeeID, "E87654321");

    // 打印信息
    printf("Person 1: %s, Age: %d, Birthdate: %04d-%02d-%02d, Student ID: %s\n",
           p1.name, p1.age, p1.birthdate.year, p1.birthdate.month, p1.birthdate.day, p1.id.studentID);

    printf("Person 2: %s, Age: %d, Birthdate: %04d-%02d-%02d, Employee ID: %s\n",
           p2.name, p2.age, p2.birthdate.year, p2.birthdate.month, p2.birthdate.day, p2.id.employeeID);

    return 0;
}

解释:

  • Person 结构体包含一个嵌套的 Date 结构体和一个联合体 id,根据 isStudent 标志使用不同的 ID。
  • 联合体 id 可以存储 studentIDemployeeID,但同一时间只能使用一个。

8. 异常处理和错误处理

示例:使用返回值和错误代码进行错误处理

#include <stdio.h>
#include <stdlib.h>

// 定义错误代码
#define SUCCESS 0
#define ERROR_INVALID_INPUT 1
#define ERROR_ALLOCATION_FAILED 2

// 函数:计算数组的平均值
int calculate_average(int *arr, int size, double *average) {
    if (arr == NULL || average == NULL) {
        return ERROR_INVALID_INPUT;
    }
    if (size <= 0) {
        return ERROR_INVALID_INPUT;
    }

    long sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    *average = (double)sum / size;
    return SUCCESS;
}

int main() {
    int data[] = {10, 20, 30, 40, 50};
    double avg;
    int status = calculate_average(data, 5, &avg);

    if (status == SUCCESS) {
        printf("Average: %.2f\n", avg);
    } else if (status == ERROR_INVALID_INPUT) {
        fprintf(stderr, "Error: Invalid input provided.\n");
    } else if (status == ERROR_ALLOCATION_FAILED) {
        fprintf(stderr, "Error: Memory allocation failed.\n");
    } else {
        fprintf(stderr, "Error: Unknown error occurred.\n");
    }

    return status;
}

解释:

  • calculate_average 函数通过返回值指示操作是否成功,并通过指针参数返回结果。
  • main 函数中,根据返回的状态码进行相应的错误处理和信息输出。

这些示例涵盖了 C 语言中一些较为复杂的概念和技术。通过理解和练习这些示例,你可以更深入地掌握 C 语言的高级特性和底层操作。如果你有任何具体问题或需要进一步的解释,请随时告诉我!

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇