地址:内存中 以字节为单位 开始编号
变量在内存单元上的编号,地址是常量
1Byte = 8 bit
&取地址符号
指针: 本质 内存单元的地址
指针变量:专门存放地址的变量
(一般不做区分)
指针的字节大小不会因为数据类型而改变,都是 4字节 ,与操作系统有关
一般形式:<存储类型><数据类型> *<变量名>
int *p;//*表示p是一个指针变量,前面int表示 p 可以指向一个整型数据
char *p;//*表示p是一个指针变量,前面int表示 p 可以指向一个字符型数据
(1)指针的存储类型 指指针变量本身的存储类型
(2)指针的数据类型 指针目标 的数据类型
初始化:<存储类型><数据类型> *<变量名> = <地址量>
int a = 10;
int *p = &a;
赋值:
int a = 10;
int *p;
p = &a;
使用:
&:取变量的地址
*:取地址中的内容//单独使用时
两个互为逆运算 *p == *(&a) == a
野指针:只定义了指针,没有目标地址,会造成非法访问内存(段错误)
指针变量的运算:
本质:地址的运算
(1)算数运算 + - ++ --
int *p = &a[5];
p+n;//p+n*sizeof(p的数据类型)====>向高地址偏移n个数据
p++;//p = p+1:
++p;
p-n;//p-n*sizeof(p的数据类型)====>向低地址偏移n个数据
p--;//p = p-1:
--p;
q-p;//前提时p、q数据类型一致,结果时两个指针之间相差的元素个数
//(q-p)/sizaof(数据类型)
注:p+n 只是单纯的运算,p的指向不变
p++指向改变,指向下一个数据
(2)关系运算 >= <= > < ==
前提:指针的类型相同
p > q :比较指针变量存放地址的高低
void *指针:是一种不确定数据类型的指针,它可以指向任意的数据类型
但在使用时必须强制类型转换
为了防止野指针,int *p = NULL;
//int *p;
// p = NULL;
if(q == NULL)
{
printf("q = NULL");
retun -1;
}
二级指针:指针的指针
多级指针:指针的迭代
const 指针
const,被修饰的部分只读,限制更改
int a = 99;
int b = 80;
(1)const int *p;
//int const *p;
p = &a;
//*p = 20; error *p只读
(2) int * const p = &a;
//p = &b; error p只读
(3) const int * const p = &a;
//p = &b; error p只读
//*p = 77; error *p只读
指针和一维数组:
数组名是数组的首地址,数组在内存中连续存储
数组名的意义:int a[10];
1、a 代表数组 首元素的 首地址(地址是常量)
2、a 代表整个数组 eg:sizeof(a) 求整个数组的大小
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = a;// int *p = &a[0];
a[0] <==> *p <==> *a <==> p[0]
a[5] <==> *(p+5) <==>*(a+5) <==> p[5]
a[i] <==> *(p+i) <==> *(a+i) <==> p[i]
指针和数组名都可以表示地址 注意区别:指针是变量 地址是常量
指针与字符数组:
char ch[5] = {'h','e','l','l','o'};
char ch[6] = "hello";//本质是数组 ,改变的是数组中的内容
char *p = “hello”;
//*p = 'Q';段错误
字符串常量 将字符串常量的首地址给指针p 内容不能更改
指针和二维数组:
[]:单独使用时,有降级的作用
二维数组名:代表一行的首地址
二维数组名+1 偏移一行
数组指针:
本质:指针,指向一维数组的首地址
int a[3][2] = {{1,2},{3,4},{5,6}};
int (*p)[2];//数组指针 p类型 int (*)[2] 指向整数 步长以两个整数为单位
列数:一维数组中最多能存放的元素个数
特点:指向一片连续的空间,方便操作
a[m][n] <==> *(a[m]+n) <==> (*(a+m))[n] <==>*(*(a+m)+n)
p[m][n] <==> *(p[m]+n) <==> (*(p+m))[n] <==>*(*(p+m)+n)
二维数组中:
a[i][j] <==> p[i][j] <==> *(*(p+i)+j) <==> *(*(a+i)+j)
指针数组:
本质:数组(一维数组),数组中存放的是指针
int *p[3];
p//数组指针名 不能自加
p[0] //指针数组中的第一个元素
*p[2] //对数组中第3个元素取内容