指针二次理解
一、 指针的定义与基本用法
- 1. 变量与内存
1) 内存用于存储数据,最小单元是字节(8bit),每个单元都有一个编号(即地址:0x00000000 ----0xFFFFFFFF)
2) 变量有大小(sizeof操作符,int大小是4bit),变量的大小是指它在内存中占了几个字节
3) 变量有地址,变量的地址就是该变量在内存中的位置,用&号可以取得地址
4) 变量赋值,就是向内存中写入数据。读取变量的值,就是从内存中读取数据
5) 每个变量都有自己的内存地址(一个萝卜一个坑)
6) 程序每次运行时,变量的地址是不一样的,无法预测也不需要预测其地址
- 2. 查看变量的地址
①代码时间:
int a = 0;
double b = 0;
printf("%08X ",&a); //取变量a的地址
printf("%08X ",&b);//取变量b的地址
也可以
printf("%P ",&a); //取变量a的地址
注意:%08X 取16进制的数
%p 指针
- 3. 如何表示地址
int* :表示一个int 型变量的地址
char* :表示一个int 型变量的地址
shot* :表示一个int 型变量的地址
float* :表示一个int 型变量的地址
double* :表示一个int 型变量的地址
.......
XXX* :表示一个XXX型的变量的地址
②代码时间
int a = 10;
int* p = &a;
注:int*为指针类型,p就是指针
- 4. 关于指针
1) 指针也是变量,是可以变的
③代码时间
int a = 10;
int b = 11;
int* p = &a; //p指向a
p = &b; //p指向b
2) 不同类型的指针不能相互赋值
④代码时间
如:
int a = 10;
int* pa = &a; //pa int*型
double* pb = &a; //错!!
又如:
char a = 78;
float* p = &a; //错
3) 指针即地址,地址是整数,所以指针是一个整数类型
即:代码时间①类似
星号*的位置
int* a;
int * a;
int *a;
以上都可以
- 5. 星号操作:按地址访问
已知一个int型变量,有两种方式来该改变它的值
第一种:
int a = 0;
a = 2;
第二种:
int a = 0;
int* p = &a;
*p = 2;
*p = 100;
注:其中*p用于访问p指向的内存(读、写)
⑤代码时间
int a = 0x1314;
int* p = &a;
*p +=2
int b = *p;
int c = *p + 2;
二、 指针与数组
- 6. 在c/c++中,数组名就是地址,就是数组在内存中的位置。它表示第一个元素的地址(简称:数组的首地址)
⑥代码时间
int arr[4] = {1,2,3,4};
int *p = arr;
相当于
int* p = &arr[0]; //第一个元素的地址
- 7. 指针加减法
指针加法:后移n个元素
指针减法:前移n个元素
⑦代码时间
int arr[4] = {1,2,3,4};
int* p = arr;
p += 1; //后移一个元素
printf("%d ",*p); //结果:2
p -= 1; //前移一个元素
printf("%d ",*p); //结果:
- 8. 指针加减法与int 加减法的区别
⑧代码时间
int arr[4] = {1,2,3,4};
int* p1 = &arr[0];
int* p2 = p1 + 1;
注:对于int*来说,元素大小是4个字节,所以后移一个元素,自然是地址要加4
- 9. 指针与数组之间的关系
1) 用p指向数组中arr的任意一个元素
例如:指向arr[3]
第一种方法:p = arr + 3;
第二种方法:p = &arr[3];
2) 给数组元素赋值
第一种方法:arr[3] = 10;
第二种方法:
*(arr + 3) = 10;
或
int* p = arr + 3; *p = 10;
3) 可以把指针p当做数组使用
⑨代码时间
int arr[4] = {1,2,3,4};
int* p = arr[1]; //指针指向数组第二个元素的地址
p[0] = 100; //相当于arr[1] = 2
p[1] = 200; //相当于 arr[2] = 3
4) 数组的遍历(通过指针进行遍历)
⑩代码时间
int arr[4];
for(int* p = arr; p < arr+4; p++ )
{
printf("%d ",*p);
}
5) 越界访问
int arr[4] = {1,2,3,4};
arr[4] = 10; //运行时错误