【数据结构】【A鹿】指针提前预备知识
指针基础知识
什么是指针
指针是一种变量类型,它的值为它指向的变量的地址,指针存储了一段的内存的直接地址。
指针相关操作符
sizeof():括号放入变量或者变量类型,将会返回变量或变量类型占据的内存大小。其中任何类型的指针都只会返回4.
sizeof(int);
&:前置单目运算符,称为引用符,连接变量将会返回其地址,类型为当前变量的指针。
int a=1;
int*ptr;
ptr=&a;//a为指针类型
*:前置单目运算符,称为解引符,它有两个作用:
- 定义指针:
type *a;//定义了一个类型为type的指针
- 解除引用:连接在指针前获取指针指向变量的内容:
*ptr=10;//给被ptr指向的内存赋值
指针的使用方法
//定义方式1:
int i=10;
int *ptr=&i;
//定义方式2:
int i=10;
int*ptr;
ptr=&i;//注意此处没有使用解引符*
//输出:
printf("%p",ptr);//输出具体地址
printf("%d",*ptr);//输出所指向内容的值,格式输出符按指向内容的变量进行修改,这里默认ptr指向int变量
//输入:
scanf("%d",ptr);//输入改变ptr指向的变量i的值,这里的变量没有使用&因为ptr本身就是指针
常见问题:初学者对于
int *a
常常会认为*a是指针,事实上a才是指针变量,可以理解为int *
是int指针变量的定义符号,而a是变量名。*a
是解除引用后的指针,表示的是具体变量值而非指针。
//指针的正确定义方法:
int *a=&p;//正确
int *a;
a=&p;//正确
//下面是两种常见的错误
int *a=p;//指针报错,无法将int类分配给int*类
int *a;
*a=&p;//指针报错,无法将int*类分配给int类
指针与引用
之所以称之为指针,是因为指针并非存储数据的新变量,而是指向其他变量地址(保存其他变量地址)的变量,指针接触引用后进行赋值操作同样会影响到被指向的变量。
int*ptr;
int i=10;
ptr=&i;
*ptr=*ptr+1;//解除引用后的ptr实际上就是变量i
printf("%d",i);
//输出结果为:11
指针与数组
数组名与指针
数组名本身就是指针,如果使用解引符输出,结果总是为该数组的第一个存储值。
int i[3]={1,2,3};
printf("%d",*i);//解引符的作用是获取指针指向变量的具体值
//输出结果为:1
数组在进入函数时,是传入了自己的指针(引用传递),并没有创建一个相同的副本(值传递),使用函数内部的任何操作不需要return就会直接影响到数组本体。
void fuctt(int a[])
{
a[1] = 100;
}
int main()
{
int a[3] = { 1,2,3 };
fuctt(a);
printf("%d", a[1]);
}
//输出结果为:100
指针引用数组
当用指针引用数组时,此指针实际上就变味了该数组的别名,可以用[]
来引用数组所包含的值。
int i[3] = { 1,2,3 };
int* p ;
p=i;//p和i双方都是指针,所以不需要使用其他符号进行限制
printf("%d", p[1]);
//输出结果为:2
指向数组的指针可以用加减法来改变他指向的具体指向的是数组中的哪一个元素,如果加减结果超过了数组的元素界限,它将会指向一段垃圾内存,值没有意义。
int i[3] = { 1,2,3 };
int* p;
p = i;
printf("%d", *p);//指向首元素i[0],输出1
p++;
printf("%d", *p);//指向i[1],输出2
p = p + 2;
printf("%d\n", *p);//越界,输出一段乱码
p = p - 1;
printf("%d", *p);//返回i[2],输出3
特别的,数组名指针与指向数组的普通指针是由区别的,数组名指针是不可赋值修改的。而普通指针可以随意修改。
int i[3] = { 1,2,3 };
i++;//报错:必须是可修改的左项
指针数组
如果想用解引符定义数组,int*p[3]
会因为运算优先级导致[]
先与p结合,等价于int *(p[3])
,这称之为指针数组。
指针数组是储存指针元素的数组变量,int *(p[3])
的三个元素都是int*类型。只需要认识到这个变量是数组就可以很方便的记住了。
数组指针
如果使用括号强行让*与p先结合,int (*p)[3]
,被称为数组指针。
数组指针是一种被强制限定只能指向数组的指针,他只能指向一个元素与其[]
内数相等的数组(元素相等)。由于数组指针指向的是数组名,所以可以认为它的本质是一个二级指针。一定要和指针数组区分开,请记住指针和数组这两个词谁在后面,变量的本质就是谁。
int arr[3]={1,2,3};
int(*p)[3];
p=&a;//这里给数组名取了&引用符号,表示取用数组指针的指针,是二级指针
printf("%p",p);//p为a的地址,输出a的地址
printf("%d",**p);//p为a本身,**p=*a,输出a数组首元素
printf("%d",(*p)[0]);//p指向a[0],输出1
printf("%d",(*p)[1];//p指向a[1],输出2
名取了&引用符号,表示取用数组指针的指针,是二级指针
printf("%p",p);//p为a的地址,输出a的地址
printf("%d",**p);//p为a本身,**p=*a,输出a数组首元素
printf("%d",(*p)[0]);//p指向a[0],输出1
printf("%d",(*p)[1];//p指向a[1],输出2