一、指针的概念
1、概念:在计算机科学中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为"指针"。意思是通过它能找到以它为地址的内存单元。
2、指针变量就是用来存放地址的变量。
3、一个内存单元是一个字节,32位的机器一个指针变量占四个字节,64位的机器一个指针变量占八个字节。地址是通过地址线产生的电信号来进行编址的。
二、指针和指针类型
1、指针类型的定义方式是:type+*
如果存放的是char类型数据的地址,则就将指针定义为char*类型。
如果存放的是int 类型数据的地址,则就将指针定义为int* 类型。
如果存放的是double*类型数据的地址,则就将指针定义为double*类型
不管指针的类型是什么,它的大小都是4或8个字节,那么类型的不同有什么意义呢?
2、指针类型的意义
①指针类型决定了,指针解引用的权限有多大。
②指针类型决定了,指针走一步,能走多远。
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
short* p = (short*)arr;
int i = 0;
for (i = 0; i < 4; i++)
{
*(p + i) = 0;
}
for (i = 0; i < 5; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
三、野指针
1、野指针的成因
①指针未初始化。
②指针越界访问。
③指针指向的空间被释放。
2、如何避免野指针
①指针初始化。
<1>当明确指针该初始化为什么时,直接初始化。
<2>不知道指针该初始化为什么时初始化为NULL(空指针)
②小心指针越界。
③指针指向空间释放及时设置为NULL。
④指针使用之前检查有效性。
四、指针的运算
1、指针+-整数
2、指针-指针
①指针-指针的前提是,两个指针指向的是同一类型空间。
②指针-指针得到的是两个地址之间元素的个数。
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}
3、指针的关系运算
#define N_VALUES 5
int main()
{
int arr[N_VALUES];
int* vp = NULL;
for (vp = &arr[N_VALUES]; vp > &arr[0];)//第一种方法
{
*--vp = 0;
}
for (vp = &arr[N_VALUES-1]; vp >= &arr[0]; vp--)//第二种方法
{
*vp = 0;
}
return 0;
}
在绝大部分编译器上第二种方法还是可以完成任务的,但是我们应尽量避免这种写法,因为C语言标准并不保证它是可行的。
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较。但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
★指针可以++,数组名不能++,因为指针是一个变量,而数组名是一个常量
五、指针和数组
1、数组名是数组首元素的地址
2、arr[2]==*(arr+2)==*(p+2)==*(2+p)==*(2+arr)==2[arr]==2[p]==p[2],原因是[ ]是一个操作符,而arr和2是它的两个操作数。arr[2]和2[arr]在运行时都先转化为*(arr+2)
3、二级指针:
#include<stdio.h>
int main()
{
int a = 10;
int* pa = &a;//pa是指针变量,一级指针
int** ppa = &pa;//ppa也是指针变量,二级指针。
return 0;
}
4、指针数组
存放指针的数组
如:int * arr[ ];整型指针数组
char* arr[ ];字符指针数组
★数据在内存中存放时,是按十六进制位存放的。
如:
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
short* p = (short*)arr;
int i = 0;
for (i = 0; i < 4; i++)
{
*(p + i) = 0;
}
for (i = 0; i < 5; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
六、二级指针
二级指针变量存放的是一级指针变量的地址。
#include<stdio.h>
int main()
{
int a = 10;
int* pa = &a;//pa是指针变量,一级指针
int** ppa = &pa;//ppa也是指针变量,二级指针。
return 0;
}