前言:
指针是 语言中的一个重要概念,也是c语言的一个重要特色。正确而灵活地运用它可以有效地表示复杂的数据结构;能动态分配内存;方便地使用字符串;有效而方便地使用数组;在调用函数时能获得一个以上的结果;能直接处理内存单元地址等,这对设计系统软件是非常必要的。掌握指针的应用,可以使程序简洁、紧凑、高效。每一个学习和使用c语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就是没有掌握c语言的精华。
1、指针
1.1 指针变量
一个变量的地址称为该变量的”指针”。所以说,指针就是地址;指针也是一种数据类型,一种专门用来存放地址这种数据的数据类型。 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量,我们可以通过&(取地址操作符)取出变量的内存真实地址,把地址可以存放到一个变量中,这个变量就是指针变量。
1.1.1 指针变量的引用
#include <stdio.h>
int main()
{
int a = 10;//在内存中开辟一块int型空间;
int* p;
p = &a;//这里我们对变量a取地址,表示获得a所在空间的首地址;
return 0;
}
注意:指针的大小在32位平台是4个字节,在64位平台是8个字节。
1.1.2 指针变量初始化
指针必须进行初始化,否则就是野指针:
#include <stdio.h>
int main()
{
int* p;//局部变量指针未初始化,产生随机值
*p = 20;
return 0;
}
若实在不知道指针到底要设定指向哪里,就定义为NULL;
#include <stdio.h>
int main()
{
int* p = NULL; // 空指针
return 0;
}
1.2 指针作为函数参数
形参 -- 指针类型 变量 ,用来接收实参 (实参是要操作的内存空间的地址)
实参 -- 要修改谁,就把谁的地址传过去,但是要保证空间有效,不然指针会访问到无法访问的空间,产生段错误。
注意: 被调函数中 一定要有 *p 运算这是间接访问的操作。
nt addOne(int *n)
{
*n = *n + 1;
return *n;
}
int main(void)
{ int a = 1;
int b = 2;
int sum = 0;
add(a,b,&sum);
printf("add = %d\n",sum);
}
1.3 指针 + 一维整型数组
对于一维整型数组,数组名就是数组首元素的地址
a <=> &a[0]
a[0]的数据类型 -- int型
&a[0] 地址的类型 -- int *
int *p = a; //表示 p指向数组a
*p <=> a[0]
例题:用指针实现插入排序(写成函数形式)
void insertSort(int *begin,int *end)
{
int *p = begin;
int *q = NULL;
for (p = begin+1; p <= end; ++p)
{
int t = *p;
q = p;
while (q > begin && *(q-1) > t)
{
*q = *(q-1);
--q;
}
*q = t;
}
}
1.4. 指针运算
指针运算是指针编程中的一个重要部分,它涉及到对指针变量进行数学运算,主要是加法和减法。以下是一些常见的指针运算概念:
1. 基本运算
减法:从指针减去整数,指针的值会减少相应数量的内存单元大小。(指针没有加法运算。)
2. 指针的递增和递减:
p++:将指针p向前移动一个它所指向的数据类型的大小。例如,如果p指向一个int类型,p++会将p移动到下一个int的位置。
p--:将指针p向后移动一个它所指向的数据类型的大小。
3. 指针的偏移量:
可以对指针加上一个偏移量,如p + n,其中n是整数。这将指针向前移动n个数据项的距离。
4. 指针的比较:
可以比较两个指针是否相等或不等,也可以比较它们的大小。例如,p1 > p2表示p1指向的位置在p2之后。
5. 指针的算术运算限制:
指针的算术运算只适用于数组和指针类型。不能对函数指针或空指针进行算术运算。
6. 指针的地址运算:
可以使用`&p`获取指针变量`p`本身的地址。
7. 指针的间接引用:
使用*p可以访问指针p所指向的内存地址中存储的值。
8. 指针的指针:
可以有指向指针的指针,例如int **pp;,pp是一个指向int*的指针,即它指向另一个指向int的指针。
9. 指针数组:
指针可以存储在数组中,每个数组元素都是一个指针。
10. 指针和数组的关系:
数组名可以作为指向数组第一个元素的指针使用,例如int arr[10];,arr就是一个指向int的指针。
11. 指针的动态分配:
使用malloc、calloc、realloc等函数分配内存时,返回的是一个指针,指向分配的内存块的起始地址。
指针运算是C语言和其他一些低级语言中非常强大的特性,但也需要谨慎使用,因为错误的指针运算可能导致程序崩溃或不可预测的行为。