每日一个C语言知识:C 指针

C语言指针详解

1. 什么是指针?

指针是一个变量,其值是另一个变量的内存地址。简单来说,指针就是存储地址的变量。

指针的核心概念

  • 每个变量都有内存地址
  • 指针存储这些地址
  • 通过指针可以间接访问和修改变量的值

2. 指针的基本概念

C语言指针 基本指针 指针运算 指针与数组 多级指针 函数指针 声明和初始化 解引用 算术运算 关系运算 数组名即指针 指针访问数组 指向指针的指针 回调函数


3. 基本指针操作

指针的声明和使用
c 复制代码
#include <stdio.h>

int main() {
    int number = 42;
    int *ptr;  // 声明一个整型指针
    
    printf("=== 基本指针操作 ===\n");
    
    // 获取变量的地址
    ptr = &number;  // & 是取地址运算符
    
    printf("变量number的值: %d\n", number);
    printf("变量number的地址: %p\n", &number);
    printf("指针ptr的值: %p\n", ptr);
    printf("指针ptr指向的值: %d\n", *ptr);  // * 是解引用运算符
    
    // 通过指针修改变量的值
    *ptr = 100;
    printf("通过指针修改后number的值: %d\n", number);
    
    // 指针的大小
    printf("指针ptr的大小: %zu 字节\n", sizeof(ptr));
    printf("int的大小: %zu 字节\n", sizeof(int));
    printf("double指针的大小: %zu 字节\n", sizeof(double*));
    
    return 0;
}
不同类型的指针
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 不同类型的指针 ===\n");
    
    int integer = 10;
    float floating = 3.14;
    char character = 'A';
    double double_value = 2.71828;
    
    // 声明不同类型的指针
    int *int_ptr = &integer;
    float *float_ptr = &floating;
    char *char_ptr = &character;
    double *double_ptr = &double_value;
    
    printf("整型指针:\n");
    printf("  值: %d, 地址: %p, 指针值: %p\n", integer, &integer, int_ptr);
    
    printf("浮点型指针:\n");
    printf("  值: %.2f, 地址: %p, 指针值: %p\n", floating, &floating, float_ptr);
    
    printf("字符型指针:\n");
    printf("  值: %c, 地址: %p, 指针值: %p\n", character, &character, char_ptr);
    
    printf("双精度指针:\n");
    printf("  值: %.5f, 地址: %p, 指针值: %p\n", double_value, &double_value, double_ptr);
    
    // void指针(通用指针)
    void *void_ptr = &integer;
    printf("void指针: %p\n", void_ptr);
    // printf("*void_ptr = %d\n", *void_ptr);  // ❌ 错误:void指针不能直接解引用
    
    return 0;
}
指针的初始化和NULL指针
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 指针初始化和NULL指针 ===\n");
    
    int x = 50;
    
    // 正确的指针初始化方式
    int *ptr1 = &x;           // 初始化时赋值
    int *ptr2 = NULL;         // 初始化为NULL
    int *ptr3;                // 未初始化(危险!)
    
    printf("ptr1: %p, 指向的值: %d\n", ptr1, *ptr1);
    printf("ptr2: %p\n", ptr2);
    printf("ptr3: %p (未初始化)\n", ptr3);
    
    // NULL指针检查
    if (ptr2 == NULL) {
        printf("ptr2是NULL指针,不能解引用\n");
    }
    
    // 危险的未初始化指针
    // printf("*ptr3 = %d\n", *ptr3);  // ❌ 未定义行为!
    
    // 安全的指针使用
    ptr3 = &x;  // 现在ptr3是安全的
    printf("ptr3现在指向: %p, 值: %d\n", ptr3, *ptr3);
    
    return 0;
}

4. 指针运算

指针算术运算
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 指针算术运算 ===\n");
    
    int numbers[] = {10, 20, 30, 40, 50};
    int *ptr = numbers;  // 指向数组的第一个元素
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("数组: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    printf("指针初始位置: %p, 值: %d\n", ptr, *ptr);
    
    // 指针加法
    ptr = ptr + 1;
    printf("ptr + 1: %p, 值: %d\n", ptr, *ptr);
    
    ptr = ptr + 2;
    printf("ptr + 2: %p, 值: %d\n", ptr, *ptr);
    
    // 指针减法
    ptr = ptr - 1;
    printf("ptr - 1: %p, 值: %d\n", ptr, *ptr);
    
    // 指针递增递减
    ptr++;  // 移动到下一个元素
    printf("ptr++: %p, 值: %d\n", ptr, *ptr);
    
    ptr--;  // 移回前一个元素
    printf("ptr--: %p, 值: %d\n", ptr, *ptr);
    
    // 指针差值
    int *first = &numbers[0];
    int *last = &numbers[4];
    printf("第一个和最后一个元素的差值: %ld\n", last - first);
    
    return 0;
}
指针关系运算
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 指针关系运算 ===\n");
    
    int arr[] = {1, 2, 3, 4, 5};
    int *ptr1 = &arr[1];  // 指向第二个元素
    int *ptr2 = &arr[3];  // 指向第四个元素
    
    printf("arr[1] = %d, 地址: %p\n", arr[1], ptr1);
    printf("arr[3] = %d, 地址: %p\n", arr[3], ptr2);
    
    // 指针比较
    if (ptr1 < ptr2) {
        printf("ptr1在ptr2之前\n");
    }
    
    if (ptr1 > ptr2) {
        printf("ptr1在ptr2之后\n");
    }
    
    if (ptr1 == &arr[1]) {
        printf("ptr1指向arr[1]\n");
    }
    
    if (ptr1 != ptr2) {
        printf("ptr1和ptr2指向不同的位置\n");
    }
    
    // 遍历数组使用指针
    printf("使用指针遍历数组: ");
    int *current = arr;
    for (int i = 0; i < 5; i++) {
        printf("%d ", *current);
        current++;  // 移动到下一个元素
    }
    printf("\n");
    
    return 0;
}

5. 指针与数组

数组名即指针
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 指针与数组 ===\n");
    
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("数组名numbers: %p\n", numbers);
    printf("&numbers[0]: %p\n", &numbers[0]);
    printf("数组名等于第一个元素的地址: %s\n", 
           numbers == &numbers[0] ? "是" : "否");
    
    // 不同的访问方式
    printf("\n=== 数组元素访问方式 ===\n");
    for (int i = 0; i < size; i++) {
        printf("numbers[%d] = %d\n", i, numbers[i]);
        printf("*(numbers + %d) = %d\n", i, *(numbers + i));
    }
    
    // 指针可以像数组一样使用
    int *ptr = numbers;
    printf("\n指针像数组一样使用:\n");
    for (int i = 0; i < size; i++) {
        printf("ptr[%d] = %d\n", i, ptr[i]);
    }
    
    return 0;
}
指针与多维数组
c 复制代码
#include <stdio.h>

#define ROWS 3
#define COLS 4

int main() {
    printf("=== 指针与多维数组 ===\n");
    
    int matrix[ROWS][COLS] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    // 使用指针访问二维数组
    printf("使用指针遍历二维数组:\n");
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d\t", *(*(matrix + i) + j));
        }
        printf("\n");
    }
    
    // 数组指针(指向整个一维数组的指针)
    int (*row_ptr)[COLS] = matrix;
    
    printf("\n使用数组指针:\n");
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d\t", row_ptr[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

6. 指针与函数

传值调用 vs 传址调用
c 复制代码
#include <stdio.h>

// 传值调用 - 接收参数的副本
void swapByValue(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    printf("函数内 - a = %d, b = %d\n", a, b);
}

// 传址调用 - 接收参数的地址
void swapByReference(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
    printf("函数内 - *a = %d, *b = %d\n", *a, *b);
}

// 返回多个值通过指针参数
void calculate(int a, int b, int *sum, int *product, float *average) {
    *sum = a + b;
    *product = a * b;
    *average = (a + b) / 2.0;
}

int main() {
    printf("=== 指针与函数 ===\n");
    
    int x = 5, y = 10;
    
    printf("交换前: x = %d, y = %d\n", x, y);
    
    // 传值调用
    swapByValue(x, y);
    printf("传值调用后: x = %d, y = %d\n", x, y);
    
    // 传址调用
    swapByReference(&x, &y);
    printf("传址调用后: x = %d, y = %d\n", x, y);
    
    // 通过指针返回多个值
    int sum, product;
    float average;
    calculate(x, y, &sum, &product, &average);
    
    printf("\n计算结果:\n");
    printf("和: %d\n", sum);
    printf("积: %d\n", product);
    printf("平均值: %.2f\n", average);
    
    return 0;
}
数组作为函数参数
c 复制代码
#include <stdio.h>

// 函数声明
void printArray(int arr[], int size);
void modifyArray(int *arr, int size);
int* findMax(int arr[], int size);

int main() {
    int numbers[] = {23, 45, 12, 67, 34, 89, 56};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("=== 数组作为函数参数 ===\n");
    
    printf("原始数组: ");
    printArray(numbers, size);
    
    // 修改数组
    modifyArray(numbers, size);
    printf("修改后数组: ");
    printArray(numbers, size);
    
    // 返回指针的函数
    int *max_ptr = findMax(numbers, size);
    printf("最大值: %d (地址: %p)\n", *max_ptr, max_ptr);
    
    return 0;
}

// 使用数组语法
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 使用指针语法(两种语法是等价的)
void modifyArray(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;  // 等价于 *(arr + i) *= 2
    }
}

// 返回指针的函数
int* findMax(int arr[], int size) {
    int *max_ptr = &arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > *max_ptr) {
            max_ptr = &arr[i];
        }
    }
    return max_ptr;
}

7. 多级指针

二级指针
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 多级指针 ===\n");
    
    int value = 100;
    int *ptr = &value;     // 一级指针
    int **pptr = &ptr;     // 二级指针
    int ***ppptr = &pptr;  // 三级指针
    
    printf("变量value: %d\n", value);
    printf("变量value的地址: %p\n", &value);
    
    printf("一级指针ptr: %p\n", ptr);
    printf("ptr指向的值: %d\n", *ptr);
    printf("ptr的地址: %p\n", &ptr);
    
    printf("二级指针pptr: %p\n", pptr);
    printf("pptr指向的值(ptr的地址): %p\n", *pptr);
    printf("pptr指向的指针指向的值: %d\n", **pptr);
    
    printf("三级指针ppptr: %p\n", ppptr);
    printf("ppptr指向的指针指向的指针指向的值: %d\n", ***ppptr);
    
    // 通过多级指针修改变量值
    **pptr = 200;
    printf("通过二级指针修改后value的值: %d\n", value);
    
    ***ppptr = 300;
    printf("通过三级指针修改后value的值: %d\n", value);
    
    return 0;
}
指针数组
c 复制代码
#include <stdio.h>

int main() {
    printf("=== 指针数组 ===\n");
    
    int a = 10, b = 20, c = 30, d = 40;
    
    // 指针数组 - 存储指针的数组
    int *ptr_array[4] = {&a, &b, &c, &d};
    
    printf("指针数组内容:\n");
    for (int i = 0; i < 4; i++) {
        printf("ptr_array[%d] = %p, *ptr_array[%d] = %d\n", 
               i, ptr_array[i], i, *ptr_array[i]);
    }
    
    // 修改通过指针数组
    *ptr_array[0] = 100;
    *ptr_array[1] = 200;
    
    printf("\n修改后:\n");
    printf("a = %d, b = %d\n", a, b);
    
    return 0;
}

8. 动态内存分配

malloc, calloc, realloc, free
c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("=== 动态内存分配 ===\n");
    
    int *dynamic_array;
    int size;
    
    printf("请输入数组大小: ");
    scanf("%d", &size);
    
    if (size <= 0) {
        printf("错误:大小必须为正数!\n");
        return 1;
    }
    
    // 使用malloc分配内存(不初始化)
    dynamic_array = (int*)malloc(size * sizeof(int));
    if (dynamic_array == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    
    printf("使用malloc分配的内存(未初始化):\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", dynamic_array[i]);  // 可能包含垃圾值
    }
    printf("\n");
    
    // 初始化数组
    for (int i = 0; i < size; i++) {
        dynamic_array[i] = i * 10;
    }
    
    printf("初始化后的数组:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", dynamic_array[i]);
    }
    printf("\n");
    
    // 使用calloc分配内存(初始化为0)
    int *another_array = (int*)calloc(size, sizeof(int));
    printf("使用calloc分配的内存(初始化为0):\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", another_array[i]);
    }
    printf("\n");
    
    // 使用realloc调整内存大小
    int new_size = size * 2;
    dynamic_array = (int*)realloc(dynamic_array, new_size * sizeof(int));
    
    // 初始化新分配的部分
    for (int i = size; i < new_size; i++) {
        dynamic_array[i] = i * 10;
    }
    
    printf("realloc后的数组:\n");
    for (int i = 0; i < new_size; i++) {
        printf("%d ", dynamic_array[i]);
    }
    printf("\n");
    
    // 释放内存
    free(dynamic_array);
    free(another_array);
    
    printf("内存已释放\n");
    
    return 0;
}
动态二维数组
c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("=== 动态二维数组 ===\n");
    
    int rows, cols;
    
    printf("请输入行数: ");
    scanf("%d", &rows);
    printf("请输入列数: ");
    scanf("%d", &cols);
    
    // 分配行指针数组
    int **matrix = (int**)malloc(rows * sizeof(int*));
    if (matrix == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    
    // 为每一行分配内存
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int*)malloc(cols * sizeof(int));
        if (matrix[i] == NULL) {
            printf("内存分配失败!\n");
            return 1;
        }
    }
    
    // 初始化矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j + 1;
        }
    }
    
    // 打印矩阵
    printf("动态二维数组:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d\t", matrix[i][j]);
        }
        printf("\n");
    }
    
    // 释放内存(按分配的顺序反向释放)
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);
    
    printf("内存已释放\n");
    
    return 0;
}

9. 函数指针

基本函数指针
c 复制代码
#include <stdio.h>

// 简单的数学运算函数
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { 
    if (b != 0) return a / b; 
    return 0;
}

// 使用函数指针作为参数
void calculate(int a, int b, int (*operation)(int, int)) {
    int result = operation(a, b);
    printf("计算结果: %d\n", result);
}

int main() {
    printf("=== 函数指针 ===\n");
    
    // 声明函数指针
    int (*func_ptr)(int, int);
    
    int x = 10, y = 5;
    
    // 使用函数指针调用不同的函数
    func_ptr = add;
    printf("加法: ");
    calculate(x, y, func_ptr);
    
    func_ptr = subtract;
    printf("减法: ");
    calculate(x, y, func_ptr);
    
    func_ptr = multiply;
    printf("乘法: ");
    calculate(x, y, func_ptr);
    
    func_ptr = divide;
    printf("除法: ");
    calculate(x, y, func_ptr);
    
    // 函数指针数组
    int (*operations[])(int, int) = {add, subtract, multiply, divide};
    const char* operation_names[] = {"加法", "减法", "乘法", "除法"};
    
    printf("\n使用函数指针数组:\n");
    for (int i = 0; i < 4; i++) {
        printf("%s: %d\n", operation_names[i], operations[i](x, y));
    }
    
    return 0;
}
回调函数
c 复制代码
#include <stdio.h>

// 回调函数类型定义
typedef int (*CompareFunc)(int, int);

// 比较函数
int ascending(int a, int b) { return a - b; }
int descending(int a, int b) { return b - a; }

// 使用回调函数的排序函数
void bubbleSort(int arr[], int size, CompareFunc compare) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (compare(arr[j], arr[j + 1]) > 0) {
                // 交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    printf("=== 回调函数示例 ===\n");
    
    int numbers[] = {64, 34, 25, 12, 22, 11, 90};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("原始数组: ");
    printArray(numbers, size);
    
    // 升序排序
    bubbleSort(numbers, size, ascending);
    printf("升序排序: ");
    printArray(numbers, size);
    
    // 降序排序
    bubbleSort(numbers, size, descending);
    printf("降序排序: ");
    printArray(numbers, size);
    
    return 0;
}

10. 实际应用示例

示例1:字符串处理工具
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 自定义字符串函数
char* myStrcpy(char *dest, const char *src);
char* myStrcat(char *dest, const char *src);
int myStrcmp(const char *str1, const char *str2);
char* myStrrev(char *str);

int main() {
    printf("=== 字符串处理工具 ===\n");
    
    // 动态分配字符串
    char *str1 = (char*)malloc(100 * sizeof(char));
    char *str2 = (char*)malloc(100 * sizeof(char));
    
    if (str1 == NULL || str2 == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    
    // 测试自定义字符串函数
    myStrcpy(str1, "Hello");
    myStrcpy(str2, "World");
    
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    
    printf("比较结果: %d\n", myStrcmp(str1, str2));
    
    myStrcat(str1, " ");
    myStrcat(str1, str2);
    printf("连接后: %s\n", str1);
    
    myStrrev(str1);
    printf("反转后: %s\n", str1);
    
    // 释放内存
    free(str1);
    free(str2);
    
    return 0;
}

// 自定义字符串复制
char* myStrcpy(char *dest, const char *src) {
    char *start = dest;
    while (*src != '\0') {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    return start;
}

// 自定义字符串连接
char* myStrcat(char *dest, const char *src) {
    char *start = dest;
    
    // 找到dest的结尾
    while (*dest != '\0') {
        dest++;
    }
    
    // 复制src到dest的结尾
    while (*src != '\0') {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    
    return start;
}

// 自定义字符串比较
int myStrcmp(const char *str1, const char *str2) {
    while (*str1 && *str2 && *str1 == *str2) {
        str1++;
        str2++;
    }
    return *str1 - *str2;
}

// 自定义字符串反转
char* myStrrev(char *str) {
    if (str == NULL) return NULL;
    
    char *start = str;
    char *end = str;
    char temp;
    
    // 找到字符串结尾
    while (*end != '\0') {
        end++;
    }
    end--;  // 指向最后一个字符
    
    // 反转字符串
    while (start < end) {
        temp = *start;
        *start = *end;
        *end = temp;
        
        start++;
        end--;
    }
    
    return str;
}
示例2:学生管理系统
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NAME_LENGTH 50

typedef struct {
    char name[MAX_NAME_LENGTH];
    int age;
    float score;
} Student;

// 函数声明
Student* createStudent(const char *name, int age, float score);
void displayStudent(const Student *student);
void updateStudentScore(Student *student, float new_score);
void freeStudent(Student *student);

int main() {
    printf("=== 学生管理系统 ===\n");
    
    // 动态创建学生
    Student *student1 = createStudent("张三", 20, 85.5);
    Student *student2 = createStudent("李四", 22, 92.0);
    Student *student3 = createStudent("王五", 21, 78.5);
    
    if (student1 == NULL || student2 == NULL || student3 == NULL) {
        printf("学生创建失败!\n");
        return 1;
    }
    
    // 显示学生信息
    printf("=== 学生信息 ===\n");
    displayStudent(student1);
    displayStudent(student2);
    displayStudent(student3);
    
    // 更新成绩
    printf("\n=== 更新成绩 ===\n");
    updateStudentScore(student3, 88.0);
    displayStudent(student3);
    
    // 学生数组
    Student *students[] = {student1, student2, student3};
    int student_count = 3;
    
    // 计算平均分
    float total_score = 0;
    for (int i = 0; i < student_count; i++) {
        total_score += students[i]->score;
    }
    printf("\n平均分: %.2f\n", total_score / student_count);
    
    // 释放内存
    for (int i = 0; i < student_count; i++) {
        freeStudent(students[i]);
    }
    
    printf("内存已释放\n");
    
    return 0;
}

// 创建学生
Student* createStudent(const char *name, int age, float score) {
    Student *student = (Student*)malloc(sizeof(Student));
    if (student == NULL) {
        return NULL;
    }
    
    strncpy(student->name, name, MAX_NAME_LENGTH - 1);
    student->name[MAX_NAME_LENGTH - 1] = '\0';
    student->age = age;
    student->score = score;
    
    return student;
}

// 显示学生信息
void displayStudent(const Student *student) {
    printf("姓名: %s, 年龄: %d, 分数: %.1f\n", 
           student->name, student->age, student->score);
}

// 更新学生成绩
void updateStudentScore(Student *student, float new_score) {
    student->score = new_score;
    printf("%s的成绩已更新为: %.1f\n", student->name, new_score);
}

// 释放学生内存
void freeStudent(Student *student) {
    free(student);
}

11. 常见指针错误

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("=== 常见指针错误 ===\n");
    
    // ❌ 错误1:使用未初始化的指针
    /*
    int *ptr;
    printf("%d\n", *ptr);  // 未定义行为
    */
    
    // ✅ 正确:总是初始化指针
    int x = 10;
    int *ptr = &x;
    printf("正确使用: %d\n", *ptr);
    
    // ❌ 错误2:访问已释放的内存
    /*
    int *dynamic_ptr = (int*)malloc(sizeof(int));
    *dynamic_ptr = 100;
    free(dynamic_ptr);
    printf("%d\n", *dynamic_ptr);  // 错误:访问已释放的内存
    */
    
    // ✅ 正确:释放后设为NULL
    int *dynamic_ptr = (int*)malloc(sizeof(int));
    *dynamic_ptr = 100;
    free(dynamic_ptr);
    dynamic_ptr = NULL;  // 防止悬空指针
    
    // ❌ 错误3:内存泄漏
    /*
    void leakMemory() {
        int *ptr = (int*)malloc(100 * sizeof(int));
        // 忘记free(ptr)
    }
    */
    
    // ✅ 正确:配对使用malloc/free
    int *safe_ptr = (int*)malloc(sizeof(int));
    if (safe_ptr != NULL) {
        *safe_ptr = 50;
        printf("安全使用: %d\n", *safe_ptr);
        free(safe_ptr);
    }
    
    // ❌ 错误4:返回局部变量的地址
    /*
    int* dangerousFunction() {
        int local_var = 100;
        return &local_var;  // 错误:返回局部变量的地址
    }
    */
    
    // ✅ 正确:返回动态分配的内存或静态变量
    int* safeFunction() {
        static int static_var = 200;  // 静态变量
        return &static_var;
    }
    
    int *result = safeFunction();
    printf("安全返回: %d\n", *result);
    
    return 0;
}

相关推荐
Scott9999HH5 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社6 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海6 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖7 小时前
JDK 26 新特性详解
java·开发语言
马优晨7 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区9 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大10 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai10 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜10 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa10 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio