一.指针:是一种基本数据类型,用于存放地址型数据。指针很灵活,是c语言中比较难的一个知识点。
二.基本数据类型的指针:int char double float long等。
以int类型的指针为例
1.声明:int *p;
int 表示p装的地址,对应的空间的数据类型;*
表示p的一个指针变量,p为指针的名字。
2.初始化与赋值(未初始化和赋值的指针称为野指针。)
假设定义 int a=10
;a的地址为:&a
;
对指针进行初始化:
int *p=&a;
声明指针变量的同时,给其赋变量的地址,也可以给其直接赋变量的地址值(一般不使用,无法确定变量的地址,编译器不同,变量的地址也有所不同,即便相同的编译器在不同的时间打开,变量的地址值也可能不同。)
3.对指针进行赋值:
int *p;
*p=&a;
先声明指针变量,然后再给其赋变量的地址。
注意:不允许存在野指针的存在。
例子:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a = 10;
int b = 20;
int *p = &a; //初始化
printf("%p,%p,%p\n", &a, p, &p);
printf("%d,%d\n", a, *p);
p = &b;//赋值
printf("%p,%p,%p\n", &b, p, &p);
printf("%d,%d\n", b, *p);
system("pause");
return 0;
}
运行结果:
注意:a.装哪块地址,就指向哪块空间。
b.类型一定要对应上,类型决定指针的读写方式。否则编译时会出现警告。
4.指针操作所指向空间。
对内存的操作,读写取。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a = 10;
int *p = &a; //这里的*是标记作用,标记p为指针变量
//读
printf("%p,%d,%d\n", p, *p, a); //这里的*是内存操作运算符号,或者解引用运算府。
//写
*p = 45;
printf("%p,%d,%d\n", p, *p, a);
//取地址
printf("%p,%p,%p\n", p, &*p, &a);
system("pause");
return 0;
}
运行结果:
*
为内存操作运算符或者解引用运算符。
使用方法*
+地址,地址必须为合法。(定义的变量,数组等)
注意:一个指针指向一个变量,*
这个指针,就是变量本身,即这里*p
就是a;
间接操作:通过p得到所装的地址值,再根据地址值操作a的空间,运行速度比较慢。
5.类型决定内存操作:所指向的空间类型是什么类型,那么*p
就一次操作多大的内存空间。例如,
int a=123;
int *p=&a;
*p=1456;//p操作四字节的内存空间,由指针变量的类型决定。int是4字节。
短字节的指针可以操作指向长的空间,操作不异常,但运行结果不对。
double d=12.2345;
int *p=&d;
长字节的指针不能操作指向短字节的空间,操作异常。
int d=123;
double *p=&d;
6.二级指针:一级指针的变量地址用二级指针来装,二级指针的变量地址用三级指针来装。
int a=10;
int *p=&a;
int* *p1=&p;
*p1
表示指针,int*
表示指向的变量类型。同理表示三级指针或者更多级的指针。
例如:
//二级指针
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a = 10;
int *p = &a;
int **p1 = &p;
/*
*p==a;
*p1==p;
**p1==*p==a;
*/
printf("%p,%p,%p,%p,%p,%p\n", &a, p, &p, p1, *p1, &p1);
printf("%d,%d,%d\n", a, *p, **p1);
system("pause");
return 0;
}
运行结果:
说明:我是边复习c语言指针等知识点的同时,边写的,用来以后自己回顾知识点。参照b站C3程序猿的视频写的,如有错误和不足,请原谅。