1:什么是指针:
要学习指针,首先我们要知道什么是指针,指针是c语言特有的内容,通俗来说,指针是指向地址的一个变量,这个变量里面存放的就是地址,也就是说,指针就是地址,当然,通常我们口头上说的指针是指针变量。
2:指针类型:
首先我们先定义一个指针:
int main(){
int* a=10;
char* b='abc';
return 0;
}
如图所示:*表示的就是这个变量a是一个指针,而它前面的数据类型int表示的就是a所指向的对象10是一个整型数据,所以用int的数据类型,同理,下面的b指向的一个字符串,所以要用char的数据类型。
3:指针的大小:
32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。
4:指针变量类型的意义:
1:决定了指针在被解引用的时候访问几个字节:如果是int* 类型的指针,解引用访问4个字节,如果是char* 类型的指针,解引用访问1个字节。
2:决定了指针在+1或-1操作时候,跳过几个字节,决定了指针的步长。
5:const修饰指针变量:
1:const如果放在 * 的左边,修
饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本⾝的内容可变。
2: const如果放在 * 的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
可以看到,如果是被const修饰的指针是不能被修改的。但指针变量本身还是可以修改。
如果const在右边,可以看到,指针变量p不能修改,但是p所指向的内容还是可以改变。
如果是左右2边都被const修饰,那么指针所指向的内容和指针变量都不可以改变。
6:指针的运算:
指针± 整数:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//p+i 这⾥就是指针+整数
}
return 0;
}
上述代码就是通过对指针的加实现数组的遍历,首先p指向数组的第一个元素,每次加上i的变量,最后解引用就能实现,因此我们可以得到结论:指针加或减去指针还是指针;并且因为是整型指针,也就是说每一次加1都是跳过了4个字节。也就正好是下一个元素的位置。
指针-指针:
通过上述代码来分析,首先我们用p指向数组的第一个元素,然后我们定义一个指针变量q指向数组的最后一个元素,然后我们让指针p减去指针q得到-9;恰好是2个指针之间的数组元素个数。因此我们得到结论:指针-指针的绝对值就是指针之间的元素个数。注意:指针+指针是没有意义的。
7:野指针:
造成野指针的原因有3个:
第一个:未初始化。
第二个:越界访问。
第三个:调用函数内的局部变量。
那么如何避免野指针的出现呢?我们可以使用assert()断言函数。这里就不详细解释了。后面专门出一期讲解。
8:二级指针:
所谓二级指针,就是指向指针的指针。
int a = 10;
int* b = &a;
int** c = &b;
*b = 20;
**c = 30;
printf("%d ", a);//30
这里的c就是一个二级指针,它是指向指针b的地址的。其实也很好理解, 二级指针有2颗*,其中一颗表示它是一个指针变量。另一颗表示它所指向的对象的数据类型,也就是b,b的数据类型就是int*,所以就是二级指针。要注意的是,要想使用二级指针里的内容,需要解引用两次。
这一期我们就先了解这么多,后面我还会出几期更加重要的知识,这一期只是入门了解一下指针。如果有不懂的地方在评论区留言哦!