C语言文章更新目录
C语言学习资源汇总,史上最全面总结,没有之一
C/C++学习资源(百度云盘链接)
计算机二级资料(过级专用)
C语言学习路线(从入门到实战)
编写C语言程序的7个步骤和编程机制
C语言基础-第一个C程序
C语言基础-简单程序分析
VS2019编写简单的C程序示例
简单示例,VS2019调试C语言程序
C语言基础-基本算法
C语言基础-数据类型
C语言中的输入输出函数
C语言流程控制语句
C语言数组——一维数组
C语言数组——二维数组
C语言数组——字符数组
C语言中常用的6个字符串处理函数
精心收集了60个C语言项目源码,分享给大家
C语言核心技术——函数
C代码是怎样跑起来的?
C语言实现字符串的加密和解密
C语言——文件的基本操作
使用C语言链表创建学生信息并且将信息打印输出
图解C语言冒泡排序算法,含代码分析
实例分析C语言中strlen和sizeof的区别
开发C语言的3款神器,VS2019、VScode和IntelliJ Clion
动图图解C语言选择排序算法,含代码分析
动图图解C语言插入排序算法,含代码分析
C语言指针数组和数组指针详解
5分钟搞懂C语言中的传值和传址
C语言——动态数组的创建和使用
C语言中#include<…>和#include“…“的区别
2024年C语言最新经典面试题汇总(1-10)
2024年C语言最新经典面试题汇总(11-20)
C语言中如何动态分配内存并进行操作
如何在C语言中使用命令行参数
C语言实例专栏(持续更新中…)
正文
C语言指针是C语言中最重要的部分之一,也是初学者比较难以理解的概念之一。本文将为大家详细解说C语言指针的相关知识。
-
指针的基本概念
- 指针的声明与初始化:声明一个指针时,我们不仅指定指针的类型,还表明它能存储哪种类型变量的地址。
例如,int *p;
声明了一个可以存储整型变量地址的指针p
。
初始化指针,比如int x = 10; int *p = &x;
,这里p
被赋予了变量x
的内存地址,可以用*p
来访问x
的值。 - 空指针:在C语言中,
NULL
或(void*)0
表示空指针,代表指针不指向任何有效地址。声明和初始化为空指针有利于预防未初始化指针引发的问题。
- 指针的声明与初始化:声明一个指针时,我们不仅指定指针的类型,还表明它能存储哪种类型变量的地址。
-
指针的解引用
- 读取值:通过
*指针名
的方式解引用指针,可以从内存中读取值。例如int val = *p;
将p
指向的内存地址处的整数值赋给val
。 - 写入值:通过
*指针名 = 值
的方式可以修改指针指向内存地址处的值。例如*p = 20;
将20
写入p
指向的内存地址。
- 读取值:通过
-
指针运算
- 指针加减:对于指向数组的指针,执行加减运算时,它并非简单地加减数字,而是根据指针类型自动调整偏移量,使其按相应类型长度跳转。例如,对于
int *p
,p + 1
实际上使指针移动到数组中下一位整数的位置。 - 关系运算:同类型的指针可以进行相等性和顺序性的比较。例如,如果
p
和q
都指向同一个数组内的元素,则p < q
可以判断p
是否在q
之前。
- 指针加减:对于指向数组的指针,执行加减运算时,它并非简单地加减数字,而是根据指针类型自动调整偏移量,使其按相应类型长度跳转。例如,对于
-
指针与数组
- 数组名作为指针:在C语言中,数组名可被当作指向数组首元素的常量指针,但它不可被重新赋值。例如,数组
int arr[5];
中,arr
可视作int *const arr
,arr + i
实际上是对数组元素的偏移访问。 - 指针遍历数组:通过让指针从数组首地址开始,每次递增指针来遍历整个数组,这是一种常见的高效遍历方式,因为指针自增相当于按元素类型长度移动。
- 数组名作为指针:在C语言中,数组名可被当作指向数组首元素的常量指针,但它不可被重新赋值。例如,数组
-
指针与字符串
- 在C语言中,字符串实际上是字符数组,最后一个字符为’\0’作为结束标记。例如,
char *str = "Hello";
中,str
指向字符串的第一个字符 ‘H’。通过递增指针str++
,我们可以依次访问后续字符直至遇到 ‘\0’。
- 在C语言中,字符串实际上是字符数组,最后一个字符为’\0’作为结束标记。例如,
-
指针与函数
- 传址调用:在函数调用中,通过传递变量的地址而不是复制变量的值,可以让函数直接修改原始变量的值。例如,
void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
可以交换两个整数的值。 - 返回指针:函数可以返回指向动态分配内存或静态/全局变量地址的指针。例如,
char *getStr() { char str[] = "Example"; return str; }
返回一个指向字符串常量区的指针,但由于是局部变量,这样返回可能会导致未定义行为。
- 传址调用:在函数调用中,通过传递变量的地址而不是复制变量的值,可以让函数直接修改原始变量的值。例如,
-
动态内存分配
- 使用
malloc()
、calloc()
、realloc()
函数可以动态分配内存,这些函数会返回指向新分配内存区域的指针。如int *ptr = (int*)malloc(5 * sizeof(int));
会分配可以存储5个整数的空间。当不再需要这块内存时,必须使用free(ptr);
来释放,否则会导致内存泄漏。
- 使用
-
多级指针
- 多级指针是指一个指针指向另一个指针的情况。例如,
int **pp
是一个指向int *
类型指针的指针。在实际应用中,多级指针常见于处理二维数组、指针数组或链表等场景。
- 多级指针是指一个指针指向另一个指针的情况。例如,
-
结构体与指针
- 结构体指针可以用来操作结构体实例。声明一个指向结构体类型的指针并初始化,如
struct Student *stu = malloc(sizeof(struct Student));
之后,可以通过解引用或箭头操作符 (->
) 访问结构体成员。例如,(*stu).age
或stu->age
可以访问age
成员。此外,结构体内部成员也可以是其他结构体或指针类型,此时可以声明指向结构体内部指针成员的指针。
- 结构体指针可以用来操作结构体实例。声明一个指向结构体类型的指针并初始化,如
-
总结
C语言中的指针是程序设计的强大工具,能够极大地提高程序效率,同时也增加了程序设计的复杂性,要求开发者对其有深入理解和谨慎使用。指针的正确使用可以帮助解决很多实际编程问题,但也容易成为错误的来源,因此在编写涉及指针的代码时应格外小心。