想必大家对于指针已经不陌生了,指针也可以称为指针变量,顾名思义,就是存放地址的变量。指针的存在方便我们后续对于该变量所指向的内存空间的调用或修改。下面让我再进一步深入地带大家了解指针。
1.指针变量的类型
指针的类型的确是多种多样的,不光有整型家族的指针,也有结构体指针,函数指针等等。他们都是指针,但是指针变量的大小与指针的类型无关(在32位系统下为4字节 在64位系统下为8字节)。这时候大家可能会有些疑惑,那么把指针的类型进行统一不是更方便吗? 实则不然,他们其实还是存在细微差别的。下面请看代码:
int main()
{
int arr[10] = { 1,2,3,4,5};
int* a = arr;
char* b = (char*)arr;
char* c = (char*)arr;
printf("%d %d %d", *(a+1), *(b+1),*(c+4));
return 0;
}
可以看到,让int、char指针分别加1再解引用后得到了不同结果,但是char指针加4后解引用结果相同。这就是因为指针所指向的对象类型不同造成的差别。
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。 ⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。
2.关于指针的运算
1.指针+-整数
根据上文所知,指针+-整数跳过的字节数是根据该指针变量所指向的类型确定的。如果+1(int类型指针跳过4字节,而char类型指针跳过1字节)。这里就不再赘述了。
2.指针-指针
那么指针-指针代表什么呢? 下面再看一个例子:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* a = arr;
int* b = arr + 9;
char arr1[10] = "abcdef";
char* c = arr1;
char* d = arr1 + 5;
printf("%d %d", b - a,d - c);
return 0;
}
可见两个同类型指针相减得到的是两个指针之间所指向对象的个数,所以并不是字节数的大小。
3.关于空指针与野指针
空指针与野指针具有不同的概念。
1. 空指针:我们常见的空指针一般指向0地址,即空指针的内部用全 0 来表示。空指针可以确保不指向任何对象或函数。所以当我们设置一个指针变量却还不知道他指向何处时,可以先让他等于NULL,即设置成空指针再做打算。
2. 野指针:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。
因此野指针可能指向任何对象或函数。因此,在使用指针时一定要规避野指针,防止他对数据进行不可知的修改。
关于野指针的类型:a.未初始化的指针 b.指针的越界 c.指针指向的空间已释放
4.const修饰指针
const的使用也在指针中十分常见,如我们在clibrary中搜索 strlen 函数:
参数中const修饰指针 目的是防止指针所指向的对象在函数的定义过程中发生改变。
const修饰指针有两种类型:
const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。 但是指针变量本⾝的内容可变。
const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。