C语言入门:指针

目录

一 简介

二 指针的概念与声明

三 指针变量的赋值与初始化

四 指针与数组的关系

五 指针与函数参数:传递数组、修改实参

六 指向指针的指针与多级指针

七 动态内存管理:malloc()、calloc()、realloc()与free()


一 简介

C语言指针是一种特殊变量,用于存储内存地址。它允许直接操作内存,提供了对数据及其所在位置的灵活控制。指针变量声明时需指定其指向的数据类型,如 int *p; 表示p是一个指向整数的指针。通过使用解引用符 * 访问指针所指向的内存位置的值,如 *p。取址运算符 & 获取变量的地址赋给指针,如 p = &x; 将变量x的地址赋予p。指针可以进行算术运算,基于数据类型调整偏移量,实现连续内存区域(如数组)的遍历。指针与数组紧密关联,数组名实质上是数组首元素的地址。此外,指针还可指向结构体、函数等。理解和恰当地使用指针是掌握C语言的核心技能之一。

二 指针的概念与声明

指针是C语言中的一个核心概念,它是一种特殊的变量,用于存储其他变量的内存地址。声明指针时,需指定其数据类型,表示它能存储对应类型变量的地址。声明格式为:

数据类型 *指针名;

其中,星号 (*) 表明这是一个指针变量,数据类型 指定了指针所指向的变量类型。例如:

int *pi;  // 声明一个指向整型变量的指针 pi
char *pc; // 声明一个指向字符型变量的指针 pc

三 指针变量的赋值与初始化

指针变量的赋值是将其设置为另一个变量或内存区域的地址。赋值通常使用取址运算符 & 来获取目标变量的地址:

int x = 10;
int *px = &x;  // px 被初始化为整型变量 x 的地址

初始化与赋值类似,但通常在声明时完成,确保指针在使用前已有一个有效的地址:

int y = 20;
int *py = NULL; // 初始化为空指针(NULL 或 0),表示尚未指向任何地址
py = &y;        // 后续赋值,使 py 指向 y

// 或者直接在声明时初始化
int *pz = &z;

四 指针与数组的关系

数组名在C语言中被视为指向数组首元素的指针常量。这意味着可以使用指针来遍历数组:

int arr[5] = {1, 2, 3, 4, 5};
int *parr = arr; // parr 等价于 &arr[0]

for (int i = 0; i < 5; ++i) {
    printf("%d ", *parr);  // 输出当前元素
    parr++;                // 移动到下一个元素
}

此外,数组作为函数参数时,实际上是传递数组的首地址,通过指针访问数组元素。例如:

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

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    print_array(numbers, sizeof(numbers) / sizeof(numbers[0])); // 传递数组首地址及元素数量
}

五 指针与函数参数:传递数组、修改实参

通过指针,函数可以修改实参(即调用者提供的变量)的值。这对于普通变量和数组都很重要。对于数组,虽然不能直接作为参数传递整个数组,但可以通过传递数组首地址(即指针)来达到修改数组元素的目的:

void modify_array(int *arr, int n, int value) {
    for (int i = 0; i < n; ++i) {
        arr[i] *= value;  // 修改数组元素
    }
}

int main() {
    int nums[] = {1, 2, 3, 4, 5};
    modify_array(nums, 5, 2);  // 通过指针修改数组元素,所有元素乘以2
}

六 指向指针的指针与多级指针

指向指针的指针(二级指针)存储的是另一个指针变量的地址。多级指针以此类推,可以用于处理复杂的内存结构,如动态多维数组、链表等。声明和使用示例:

int x;
int *px = &x; // 指针 px 存储变量 x 的地址
int **ppy = &px; // 指向指针的指针 ppy 存储指针 px 的地址

// 使用多级指针访问值
*x = 10;
**ppy = 20;  // 等同于 *px = 20; 和 x = 20;

// 多级指针在处理动态二维数组时很有用
int (*arr)[5];  // 声明一个指向长度为5的一维数组的指针
arr = malloc(sizeof(*arr) * 3);  // 分配动态二维数组(3行,每行5列)

// 使用二级指针访问数组元素
*(arr + 1)[2] = 42;  // 设置 arr[1][2] = 42

七 动态内存管理:malloc()calloc()realloc()free()

动态内存管理是C语言中通过指针操作的重要部分。以下是一些关键函数的简要说明:

  • void* malloc(size_t size): 分配size字节的未初始化内存,返回指向这块内存的指针。若分配失败,返回NULL

  • void* calloc(size_t num, size_t size): 分配num个大小为size字节的连续内存块,并将所有字节初始化为零。返回指向首块内存的指针。同样,分配失败时返回NULL

  • void* realloc(void* ptr, size_t new_size): 改变已分配内存区域的大小。ptr是先前通过malloccallocrealloc分配的内存区域的起始地址。new_size是新大小。如果成功,返回指向新(可能已移动)内存区域的指针;否则返回NULL。若ptrNULL,行为类似于malloc(new_size)

  • void free(void* ptr): 释放由malloccallocrealloc分配的内存区域。传入ptr为待释放内存的起始地址。使用后未释放的内存会导致内存泄漏。

示例:

int *dynamic_array = malloc(10 * sizeof(int));  // 分配10个整数的空间
if (dynamic_array == NULL) {
    // 处理错误
}

// 使用动态数组...
dynamic_array[5] = 123;

// 不再需要时释放内存
free(dynamic_array);
dynamic_array = NULL;  // 避免悬挂指针

  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JJJ69

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值