学了一段时间的C语言指针部分,稍作总结:
操作符
首先是关于指针的操作符,分别是&,取地址操作符;*,解引用操作符。
如果我们在C语言编译器里定义一个变量a
int main()
{
int a = 0;
return 0;
}
此时变量在内存存放需要空间,而指向这个空间的地址,我们可以用指针变量p来表示
int main()
{
int a = 0;
int* p = &a;
return 0;
}
此时p为整型指针变量,指向a在内存中第一个字节的地址。p的类型为int*,其中*可以理解为是指针变量,而int为p指向的变量的类型为整型int。
指针内存
除此之外,指针变量也是变量,也需要在内存申请空间存放指针变量,进而指针变量也可以定义指针变量来指向它,而指针变量存放的都是地址,所需要的空间根据计算机不同而不同——在32位机器上,地址为32个0/1序列(二进制),需要32个比特,也就是4个字节的空间;64位则需要64个比特,8个字节的空间。
并且指针类型还可以决定指针进行解引用操作时访问多大的空间:
比如用整型定义变量a,但用char*指针指向a的地址,则如果解引用p的话,只用到整型四个字节的第一个字节,受p的类型影响
int main()
{
int a = 0;
char* p = &a;
return 0;
}
指针类型还决定了指针的步长,即向前(+1)向后(-1)走一步的距离,即如果定义
int main()
{
int a = 0;
char* p = &a;
int* q = &a;
p++;
q++;
return 0;
}
此时p和q指向的地址不同
因为步长不同,p+1加一个整型的步长(4个字节),q+1加一个字符类型步长(1个字节)所以指向的地址差了三个字节。
const修饰指针
接下来说明一下const修饰的指针变量,其实感觉和const修饰变量可以类比:
主要分const加在*前和*后两种情况,
1.*前:修饰这个指针变量指向的变量,即把a固定,不可修改,而p变量本身可以指向其他的变量。
2.*后:相反p不可修改,但*p即解引用后的只想的变量可以修改。
int main()
{
int a = 0;
const int *p = &a;//等价于int const*p = &a
int* const q = &a;
return 0;
}
指针运算
指针之间可以进行比较大小,因为由高地址和低地址;可以进行减法,结果为地址间的元素个数;但是不可以进行加法(无意义)。这些都是基于指针指向的是同一块连续的空间,比如数组内各个元素的地址。
野指针
野指针即指向位置不可知/随机的/不正确的/无明确限制的指针。
成因有1.未初始化
2.越界访问
3.指向的空间释放
对应的解决方法可有1.初始化:指向NULL即(void*) 0,但void*的指针无法直接使用,需注意。
2.小心指针越界。
3.及时置为NULL指针。
4.避免返回局部变量地址。
int* test()
{
int n = 0;
return &n;
}
int main()
{
int a = 0;
int *p = &a;
p = test();//p此时为野指针,因为n为局部变量,空间已释放
return 0;
}
待续。。。