指针
指针的定义
指针 即 地址——指向数据的地址
地址的定义
操作系统对于内存的编号
每一个变量都会由电脑分配内存 编号
地址属于一种虚拟内存,每次运行都会改变(对于一般情况下的变量而言)
取地址符&
printf("地址:%p",&a); //%p 打印 地址的转义字符
// 所输出的地址是一个16进制数字 一个整数
指针变量
创建
//类型* 变量名;
int* p;
//初始化
int x = 10;
int* p = &x;
两个类型
- 指针变量的类型:去掉变量名剩下的就是类型———— 例如 int*
- 指针所指向的类型(指针操作数据的类型):去掉变量名和*————例如 int
- 指针运算需要保持两个类型的一致性
空类型的指针
void* a; //可以操作任何类型的地址
int* num = NULL;
//c语言中NULL 赋值指针为0的地址!
指针变量访问数据
指针变量访问数据**(即访问该内存下存储的数据)**的时候,一定要有存储变量的地址
//访问数据的方法
1. *指针变量
2. 指针变量[0]
//野指针:没有指向的指针
//悬浮指针:指针开始有指向,后面没有了指向
任何类型的 指针所占用的内存大小都是一样的
万能指针访问数据
必须做目标类型的强制转换
//万能指针做目标类型的强制转换
int x = 10;
void* p=&x;
printf("%d",*((int*)p));
ptintf("%d",((int*)p)[0]);
指针的操作
指针的移动
指针的移动 由 数据类型 所决定——对指针变量做加减法运等同于指针的移动
例如:对于 整型变量(int)每移动一位,内存地址移动四个字节
对于字符变量(char)每移动一位,内存地址移动一个字节
//公式:p(初始地址)+ n(移动的位置数) == p+(sizeof(指针所指向的类型)*n);
指针操作数组
//指针遍历数组的方式
int a[]={1,2,3,4,5,6};
int* point = &a[0]; //指针指向数组的第一个元素,即可将指针名当做数组去用
for (int i = 0; i<6; i++)
{
printf("%d",point[i]);
}
for(int i = 0; i < 6; i++)
{
printf("%d",*(point + i));
}
for(int i = 0; i< 6; i++)
{
printf("%d,(point + i)[0]");
}
数组名 ± i ——表示第几个元素地址——等效于&数组[i]
指针名 ± i——表示指针初始位置 ± i后的位置——等效于&指针名
//数组下标与指针下标的区别
int a[3] = {1,2,3};
int* b=&a[2];
printf("a+2:%p\n&a[2]:%p\n",a + 2,&a[2]);
//表示 数组a的 第二个数据的位置 即输出的 a[1]的位置
printf("%d",b[-1]);
//指针负下标表示从初始位置往前移,有意义 即输出a[1]存储的数据
指针操作字符串
//求字符串可见长度
char string1[] = "ILoveYou" ;
char* a = string1 ;
int num = 0;
while(*a++ != '\0') //字符串由\0结尾, 由指针逐个指向字符串数组每个位置的数据直到读取到\0时,终止读取,从而根据循环次数获得字符串可见长度
{
num++;
}
//指针比较字符串
//指针反转字符串
区分指针数组 和 数组指针
指针数组: 本质是一个数组 ——多个指针
char* str[3]= {"iLoveYou","iMissYou","12345"};
//优势:每一行长度可以不同。弊端:不可修改
//每一个str[i]都是一个 char* 类型的指针
数组指针: 本质是一个指针
int(*parr)[3] =NULL;
//用来操作二维数组
//操作二维数组的列数是固定的
//指针 parr ———指向一个 长度为3的一维数组
const与指针变量
const函数作用
const用来定义常量,被const修饰的变量将不再改变。
创建
//1. const修饰变量num
const int num = 0;
const int num2 = 0 ;
const int* p1 = NULL; //等效与int const* p2 = NULL;写在*前 限定了指针所指向的数据
p1=#
p1=&num2; //因此这种情况下指针指向地址可以修改 但是指针指向的数据不可修改
// 2.const 修饰指针
const int* const p3 =NULL;//等效于 int const* cosnt p4 =NULL; 限定了指针,指针不可以改变指向,创建时指向则固定指向。
行指针 列指针
列指针 可以通过指针访问某一列元素
行指针 无法访问某一列具体元素
int array[2][3]={1,2,3,4,5,6};
printf("%p\n",array);
printf("%p\n",array+1); //偏移一行
printf("%p\n",array[0]);
printf("%p\n",array[0]+1);//偏移一列 列指针
printf("%p\n",&array[0][0]);
printf("%p\n",array[0][0] + 1); //偏移一列 同上
printf("%p %p",&array,&array[0][0]); //对于取数组名地址 和取数组第一个数据的地址是一样的,但是每次偏移偏移量不同