Administrator
Administrator
发布于 2024-09-05 / 22 阅读
0
1

第8章:指针

8.1 指针的基本概念

1. 什么是指针

指针是一个变量,它的值是另一个变量的地址。通过指针,我们可以间接地访问和操作内存中的数据。

声明指针变量:

数据类型 *指针变量名;

示例:

#include <stdio.h>

int main() {
    int num = 10;
    int *ptr = &num; // 声明一个指针变量ptr,并将其初始化为num的地址

    printf("Value of num: %d\n", num);
    printf("Address of num: %p\n", (void*)&num);
    printf("Value of ptr: %p\n", (void*)ptr);
    printf("Value pointed to by ptr: %d\n", *ptr);

    return 0;
}

2. 指针的运算

指针可以进行算术运算(如加法、减法),这些运算基于指针所指向的数据类型的大小。

示例:

#include <stdio.h>

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

    printf("Value at ptr: %d\n", *ptr); // 10
    ptr++; // 指向下一个元素
    printf("Value at ptr after increment: %d\n", *ptr); // 20

    return 0;
}

8.2 指针与数组

1. 数组名是指针

在C语言中,数组名表示数组的首地址,因此数组名可以用于指针操作。

示例:

#include <stdio.h>

int main() {
    int arr[3] = {1, 2, 3};
    int *ptr = arr; // 数组名作为指针

    printf("First element: %d\n", *ptr);
    printf("Second element: %d\n", *(ptr + 1)); // 指向下一个元素

    return 0;
}

2. 指针作为数组参数

指针可以用来传递数组给函数,因为数组的实际参数是指向其首元素的指针。

示例:

#include <stdio.h>

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

int main() {
    int numbers[] = {10, 20, 30, 40};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    printArray(numbers, size);

    return 0;
}

8.3 指针与函数

1. 指针作为函数参数

函数可以接收指针作为参数,从而能够在函数内部修改实际参数的值。

示例:

#include <stdio.h>

void increment(int *x) {
    (*x)++; // 修改指针所指向的值
}

int main() {
    int num = 5;
    increment(&num); // 传递num的地址
    printf("Value after increment: %d\n", num);

    return 0;
}

2. 函数返回指针

函数可以返回指针,这在动态内存分配时特别有用。

示例:

#include <stdio.h>
#include <stdlib.h> // 包含malloc和free

int* createArray(int size) {
    int *arr = (int*)malloc(size * sizeof(int)); // 动态分配内存
    for (int i = 0; i < size; i++) {
        arr[i] = i + 1; // 初始化数组
    }
    return arr;
}

int main() {
    int size = 5;
    int *arr = createArray(size);

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

    free(arr); // 释放动态分配的内存

    return 0;
}

8.4 指针与动态内存分配

1. malloccalloc

  • malloc(memory allocation):分配指定字节数的内存块,返回指向该内存块的指针。
  • calloc(contiguous allocation):分配指定数量的内存块,每块大小相同,并初始化为0。

示例:

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

int main() {
    int *arr = (int*)malloc(5 * sizeof(int)); // 使用malloc分配内存
    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("arr[%d] = %d\n", i, arr[i]);
    }

    free(arr); // 释放内存

    return 0;
}

2. reallocfree

  • realloc:调整已分配内存块的大小。
  • free:释放已分配的内存块。

示例:

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

int main() {
    int *arr = (int*)malloc(3 * sizeof(int)); // 分配初始内存
    if (arr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // 使用数组
    for (int i = 0; i < 3; i++) {
        arr[i] = i + 1;
    }

    // 调整内存大小
    arr = (int*)realloc(arr, 5 * sizeof(int));
    if (arr == NULL) {
        printf("Memory reallocation failed\n");
        return 1;
    }

    for (int i = 3; i < 5; i++) {
        arr[i] = i + 1;
    }

    // 输出新数组内容
    for (int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    free(arr); // 释放内存

    return 0;
}

练习

  1. 编写一个程序,创建一个动态分配的整数数组,初始化为用户输入的值,并计算其平均值。
  2. 编写一个函数,使用指针参数交换两个整数的值。
  3. 编写一个程序,使用malloc分配一个字符串数组,并让用户输入每个字符串,最后打印所有字符串。
  4. 编写一个程序,使用realloc动态调整数组的大小,并在扩展后的数组中填充新数据。
  5. 编写一个函数,接受一个指向浮点数组的指针,并计算数组中所有元素的总和。

完成这些练习后,你将对指针有深入的理解。


评论