Skip to content

1. 指针和函数

1.1 函数参数传递

  • 值传递
    • 将实参的值复制一份传递给形参。
    • 形参的修改不会影响实参。
  • 指针传递
    • 将实参的地址传递给形参。
    • 形参的修改会影响到实参。
1.1.1 值传递
  • 示例
    c
    #include <stdio.h>
    
    void increment(int x) {
        x++;
        printf("Inside function: x = %d\n", x);
    }
    
    int main() {
        int a = 5;
        printf("Before function call: a = %d\n", a);
        increment(a);
        printf("After function call: a = %d\n", a);
    
        return 0;
    }
    • 输出:
      Before function call: a = 5
      Inside function: x = 6
      After function call: a = 5
1.1.2 指针传递
  • 示例
    c
    #include <stdio.h>
    
    void increment(int *x) {
        (*x)++;
        printf("Inside function: *x = %d\n", *x);
    }
    
    int main() {
        int a = 5;
        printf("Before function call: a = %d\n", a);
        increment(&a);
        printf("After function call: a = %d\n", a);
    
        return 0;
    }
    • 输出:
      Before function call: a = 5
      Inside function: *x = 6
      After function call: a = 6

1.2 返回指针的函数

  • 返回指针
    • 函数可以返回指向某个数据类型的指针。
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    int* createArray(int size) {
        int *arr = (int*)malloc(size * sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            exit(1);
        }
        for (int i = 0; i < size; i++) {
            arr[i] = i + 1;
        }
        return arr;
    }
    
    int main() {
        int *myArray = createArray(5);
        for (int i = 0; i < 5; i++) {
            printf("%d ", myArray[i]);
        }
        free(myArray); // 释放内存
        return 0;
    }
    • 输出:
      1 2 3 4 5

2. 动态内存分配

2.1 malloc 函数

  • 功能
    • 分配指定字节数的内存块,并返回指向该内存块的指针。
  • 语法
    c
    void* malloc(size_t size);
  • 参数
    • size:需要分配的字节数。
  • 返回值
    • 成功时返回指向分配内存的指针,失败时返回 NULL
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *arr = (int*)malloc(5 * sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
        for (int i = 0; i < 5; i++) {
            arr[i] = i + 1;
        }
        for (int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        free(arr); // 释放内存
        return 0;
    }
    • 输出:
      1 2 3 4 5

2.2 calloc 函数

  • 功能
    • 分配指定数量和大小的内存块,并将其初始化为零。
  • 语法
    c
    void* calloc(size_t num, size_t size);
  • 参数
    • num:元素的数量。
    • size:每个元素的大小(字节数)。
  • 返回值
    • 成功时返回指向分配内存的指针,失败时返回 NULL
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *arr = (int*)calloc(5, sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
        for (int i = 0; i < 5; i++) {
            printf("%d ", arr[i]); // 输出 0 0 0 0 0
        }
        free(arr); // 释放内存
        return 0;
    }
    • 输出:
      0 0 0 0 0

2.3 realloc 函数

  • 功能
    • 改变已分配内存块的大小。
  • 语法
    c
    void* realloc(void* ptr, size_t newSize);
  • 参数
    • ptr:指向已分配内存的指针。
    • newSize:新的内存大小(字节数)。
  • 返回值
    • 成功时返回指向重新分配内存的指针,失败时返回 NULL
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *arr = (int*)malloc(5 * sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
        for (int i = 0; i < 5; i++) {
            arr[i] = i + 1;
        }
        arr = (int*)realloc(arr, 10 * sizeof(int));
        if (arr == NULL) {
            printf("Memory reallocation failed\n");
            return 1;
        }
        for (int i = 5; i < 10; i++) {
            arr[i] = i + 1;
        }
        for (int i = 0; i < 10; i++) {
            printf("%d ", arr[i]);
        }
        free(arr); // 释放内存
        return 0;
    }
    • 输出:
      1 2 3 4 5 6 7 8 9 10

2.4 free 函数

  • 功能
    • 释放之前用 malloc, callocrealloc 分配的内存。
  • 语法
    c
    void free(void* ptr);
  • 参数
    • ptr:指向要释放内存的指针。
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *arr = (int*)malloc(5 * sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
        for (int i = 0; i < 5; i++) {
            arr[i] = i + 1;
        }
        for (int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        free(arr); // 释放内存
        return 0;
    }
    • 输出:
      1 2 3 4 5

3. 结构体和动态内存分配

3.1 结构体定义

  • 定义
    • 结构体是一种用户自定义的数据类型,可以包含多个不同类型的数据成员。
  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    
    struct Student {
        char name[50];
        int age;
        float gpa;
    };
    
    int main() {
        struct Student *student = (struct Student*)malloc(sizeof(struct Student));
        if (student == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
        strcpy(student->name, "John Doe");
        student->age = 20;
        student->gpa = 3.5;
    
        printf("Name: %s\n", student->name);
        printf("Age: %d\n", student->age);
        printf("GPA: %.2f\n", student->gpa);
    
        free(student); // 释放内存
        return 0;
    }
    • 输出:
      Name: John Doe
      Age: 20
      GPA: 3.50

3.2 动态分配数组中的结构体

  • 示例
    c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct Student {
        char name[50];
        int age;
        float gpa;
    };
    
    int main() {
        int n;
        printf("Enter the number of students: ");
        scanf("%d", &n);
    
        struct Student *students = (struct Student*)malloc(n * sizeof(struct Student));
        if (students == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
    
        for (int i = 0; i < n; i++) {
            printf("Enter details for student %d:\n", i + 1);
            printf("Name: ");
            scanf("%s", students[i].name);
            printf("Age: ");
            scanf("%d", &students[i].age);
            printf("GPA: ");
            scanf("%f", &students[i].gpa);
        }
    
        for (int i = 0; i < n; i++) {
            printf("Student %d:\n", i + 1);
            printf("Name: %s\n", students[i].name);
            printf("Age: %d\n", students[i].age);
            printf("GPA: %.2f\n", students[i].gpa);
        }
    
        free(students); // 释放内存
        return 0;
    }

总结

  1. 指针和函数
    • 值传递:将实参的值复制一份传递给形参。
    • 指针传递:将实参的地址传递给形参。
    • 返回指针的函数:函数可以返回指向某个数据类型的指针。
  2. 动态内存分配
    • malloc:分配指定字节数的内存块。
    • calloc:分配指定数量和大小的内存块,并初始化为零。
    • realloc:改变已分配内存块的大小。
    • free:释放之前分配的内存。
  3. 结构体和动态内存分配
    • 结构体定义:用户自定义的数据类型,可以包含多个不同类型的数据成员。
    • 动态分配数组中的结构体:使用 malloc 分配多个结构体的内存。

知识如风,常伴吾身