网站建设优化服务案例,网站改变配色方案,电商网课,wordpress免费企模板目录
1.概念
2.格式
3.指针操作符
4.初始化
1. 将普通变量的地址赋值给指针变量
a. 将数组的首地址赋值给指针变量
b. 将指针变量里面保存的地址赋值给另一个指针变量
5.指针运算
5.1算术运算
5.2 关系运算
指针的大小
总结#xff1a;
段错误
指针修饰
1. con…
目录
1.概念
2.格式
3.指针操作符
4.初始化
1. 将普通变量的地址赋值给指针变量
a. 将数组的首地址赋值给指针变量
b. 将指针变量里面保存的地址赋值给另一个指针变量
5.指针运算
5.1算术运算
5.2 关系运算
指针的大小
总结
段错误
指针修饰
1. const修饰
2. void
大小端
二级指针
指针和数组
1. 指针和一维数组
直接访问
间接访问
2. 指针和二维数组
直接访问
间接访问
数组指针
数组指针
定义本质是指针指向的是数组(又称行指针)
格式存储类型数据类型(*指针变量名)[列数];
大小 指针的优点
使程序更加简洁、紧凑、高效有效的表达更复杂的数据结构动态分配内存得到多余一个数的函数的返回值
1.概念
地址内存中每个字节单元都有点编号
指针指针就是地址
指针变量用于存放地址的变量叫做指针变量
2.格式
存储类型 数据类型 * 指针变量名
int* p 使用
int a5
int* pa char ch‘t’
char* pch 3.指针操作符
取地址符---取变量的地址
*取内容 ---取地址里面的内容
*aa// *和是互逆运算 // a是变量就是错的a是地址就是对的
*a
4.初始化
指针变量只使用前不仅要定义还要初始化未初始化的指针变量是不能随便使用的会产生野指针
int* p;
1. 将普通变量的地址赋值给指针变量
int a10 1int* pa//定义的同时赋值 2int* pNULL//先定义指针变量在进行赋值 pa
int* p NULL; // int *p
p a;
printf(%d %d\n, a, *p); // 打印 a 的值 10 10
printf(%p %p\n, a, p); // 打印 a 的地址*p 3;
printf(%d %d\n, a, *p); // 打印 a 的值 3 3
printf(%p %p\n, a, p); // 打印 a 的地址
a. 将数组的首地址赋值给指针变量
char str[10] hello;
char* p str; // 指针指向数组的首地址指向字符h的地址
b. 将指针变量里面保存的地址赋值给另一个指针变量
floatf 1.3;
float* p f;
float* q p; 5.指针运算
5.1算术运算
char str[32] hello;
char* p str;
p; // 指针向高地址方向移动一个数据单位看数据类型指针指向发生变化
p--; // 指针向低地址方向移动一个数据单位看数据类型指针指向发生变化 int* p; p;// 移动4字节
double*p; p; // 移动8字节 pn访问高地址方向第n 个数据的地址指针指向不会发生变化
p-n访问低地址方向第n 个数据的地址指针指向不会发生变化 偏移了多少地址(字节) n *sizeof(数据类型)
两个地址之间的差 两个地址之间相隔元素的个数
q - p两个地址之间相隔的元素个数
char str[] hello;
char* p str;
char* q p3;
printf(%d\n, q - p);
5.2 关系运算 !
指针之间的关系运算比较的是它指向地址的高低
高地址的指针大于低地址的指针
char str[32] hello;char* p1 str[1];
char* p2 str[3];p2 p1注意指向不同类型的数组指针关系运算没有意义指向不同区域的指针关系运算也没有意义
同一个数组间进行比较
指针的大小
int a 5;
int* p a; // 4
short b 2;
short* p1 b; // 4
double c 1.1;
double* p2 c; // 4szieof(指针变量名)32位操作系统指针为4字节
8位16进制表示4字节64位操作系统指针为8字节
16位16进制表示8字节
总结
1.32位操作系统指针为4字节 64位操作系统指针为8字节
2. 内存地址是固定的但是变量的地址不固定的栈区随机分配
3. 指针类型根据指针指向空间的数据类型 段错误
Segentation fault (core dumped
1) 野指针没有规定指向的指针会在内存中乱指野指针产生原因
1. 指针变量定义没赋值
2. 指针 p被 free之后没有置 NULL,会让人以为p是合法指针
解决int* p NULL;
2内存泄漏对非法空间进行赋值 指针修饰
1. const修饰
1) const int num 10; const int num 10;
num 3; int* p num;
*p 3; // 可以 2const int *p//修饰*p指针指向的内容不能更改指针指向可以修改
int const *p //也可以这样修饰*p
int num10
const int* pnum
*p20//错误因为*p被修饰 int sum20
psum//可以 3int* const p//修饰p指针的指向不能修改但是指针指向的内容可以修改
int num10
int sum20
int* const pnum
p*sum//错误
*p20//可以 4修饰函数参数 2. void
void num//不允许修饰变量void* p //p是任意类型的指针需要强转才能使用使用场景函数参数或者函数返回值注意通过void类型指针进行取内容需要对地址进行强转强转方式void* pNULL;强转int*p 取内容*int* p 大小端
TCP协议三次握手四次挥手{网编时应用}
在计算机进行超过1字节数据进行储存时会出现存储数据顺序不同的情况即大小端储存 Big-Endian(大端字节序)大端在低地址存放高字节数据高地址存放低字节数据
Little-Endian(小端字节序)小端在低地址存放低字节数据高地址存放高字节数据
举例存储数据 0x12345678起始地址 0x4000
0x4000 0x4001 0x4002 0x4003
大端0x12 34 56 78
小端0x78 56 34 12 查看电脑是大端还是小端代码如下
int a 0x12345678;char b;b (char)a;printf(%#x\n, b);// 电脑是小端网络是大端// 电脑向网络传输东西数据要从小端变成大端传出去// 网络向电脑传输东西数据要从大端转成小端接收过来
二级指针
一级指针存放变量地址
二级指针存放的是一级指针的地址
格式 存储类型 数据类型 **指针变量名
int num 10;
int *p num;
int **q p;
访问 num 的值
num *p **q
访问 num 的地址
num p *q
访问 p 的地址
p q 指针和数组
直接访问按变量的地址存取变量的值(通过数组名访问)
间接访问通过存放变量地址的变量去访问变量(通过指针访问)
1. 指针和一维数组
int a[5] {1, 2, 3, 4, 5};
int *p arr;
直接访问 int a[5] {1, 2, 3, 4, 5};
int *p a;
printf(%p %p %p\n, a, a1, a3); // 直接访问元素的地址
printf(%d %d\n, a[1], *(a1));
间接访问 int a[5] {1, 2, 3, 4, 5};
int *p a;printf(%p %p %p\n, a, a1, a2);
printf(%p %p %p\n, p, p1, p2);
printf(%d %d %d\n, *p, *(p1), *(p2));
printf(%d %d %d\n, p[0], p[1], p[2]);
a 和 p 本质上不同a地址常量, p是变量a不能执行 操作但是 p 可以访问数组元素a[i]的值
直接访问a[i] *(ai)
间接访问p[i] *(pi)访问数组元素a[i]的地址
直接访问a[i] ai
间接访问p[i] pi inta[3] {3, 2, 1};
int *p a;
printf(%d\n, *p);// 3在打印一次的话就是 2
printf(%d\n, *a); //错误a地址常量
运算方法
1) 和 *都是单目运算符优先级相同
2) 单目运算符从右向左进行运算
int a[3] {3, 2, 1};
int *p a;
printf(%d\n,下列打印);
*(p)// 3实际上指针指向到了第二个元素的地址
(*p)// 打印出来是 3实际上第一个元素值变成 4
*p // 打印出来 4自加完之后的值
(*p) // 同上
*p; // 2先将指针向高地址方向移动一个数据单位然后取地址内容
*(p); // 同上 2. 指针和二维数组
int a[2][3] {1, 2, 3, 4, 5, 6}; // a数组名表示第一行的首地址a1第二行首地址
在a前面加*表示将行地址降级为列地址
*a0第一行第一列的地址
*a1第一行第二列的地址
*(a1)第二行第一列的地址
*(a1)1第二行第二列的地址
a[0]第一行第一列的地址
a[0]1第一行第二列的地址
a[1]第二行第一列的地址
a[1]1第二行第二列的地址
直接访问 间接访问
数组指针
数组指针
定义本质是指针指向的是数组(又称行指针)
格式存储类型数据类型(*指针变量名)[列数]; int a[2][3] {1, 2, 3, 4, 5,6};
int (*p)[3] a;
pint (*)[3]; 运算三个三个运算
p可以代替a进行元素访问但是本质不同 访问 a[i][j]的地址
*(pi)j p[i][j]p[i]j 访问a[i][j]的元素
*(*(pi)j) *(p[i]j)p[i][j] 大小
sizeof(p) 4