当前位置:网站首页>初识指针笔记
初识指针笔记
2022-07-06 09:19:00 【犇犇犇犇犇犇】
- 指针是什么
- 指针和指针类型
- 野指针
- 指针和指针运算
- 指针和数组
- 二级指针
- 指针数组
指针是什么?
在计算机中,所有的数据都是存放在存储器中的,不同的数据类型占有的内存空间的大小各不相同。内存是以字节为单位的连续编址空间,每一个字节单元对应着一个独一的编号,这个编号被称为内存单元的地址。比如:int 类型占 4 个字节,char 类型占 1 个字节等。系统在内存中,为变量分配存储空间的首个字节单元的地址,称之为该变量的地址。地址用来标识每一个存储单元,方便用户对存储单元中的数据进行正确的访问。在高级语言中地址形象地称为指针。
指针和指针类型
这里我们引入代码讲解
int main() {
printf("%d \n", sizeof(int*));
printf("%d \n", sizeof(char*));
printf("%d \n", sizeof(short*));
printf("%d \n", sizeof(double*));
return 0;
}
当把这段放到编译器上跑时我们会发现他的大小都一样大,那我们为什么还要说指针类型呢。看下面一段代码
int main() {
int a = 10;
int* pa = &a;
//*pa = 0;
char* pc = &a;
//*pc =0;
printf("%p\n", pa);
printf("%p\n", pc);
return 0;
}
通过输出可以看出pa,pc此时存放的相同的地址虽然pc是char型,但是编译器只会报出一个警报类型不兼容还是让pc存储了a的地址。不过如果我们通过解引用操作来改变a存储的值时,就会有不一样的情况了,大家可以在编译器的窗口内存中观看,当我们用pa=0,此时a所有字节都变为0,当我们用pc=0,a中只有一个字节变为0。
指针的类型决定了,指针解引用操作时有着多大的权限。
int* 能够控制4个字节
char* 能够控制1个字节
double* 能够控制8个字节
除此之外,指针类型还有作用,我们继续看下一段代码
int main() {
int arr[10] = {
0 };
int* pa = arr;
//char* pc = arr;
int i = 0;
for (i = 0; i < 10; i++) {
*(pa + i) = 1;
//*(pc + i) = 1;
}
return 0;
}
当我们用内存窗口观看&arr的地址,int定义的pa控制改变的arr的值,数组的每个元素都变为了1,char定义的pc控制改变arr的值时呢,一共40个字节,只能把前10个字节变为了1.所以指针类型还决定了指针走一步能走多远(指指针的步长)。
int* p p+1 -->4;
char* p p+1–>1;
double* p p+1–>8;
野指针
野指针就是指针指向的位置是不可知的(随机的,不正确的,没有限制的)
- 指针越界访问
- 指针对已经释放了的内存访问
- 指针未初始化
int main() {
int a;//局部变量未初始化
int* pa;//局部指针变量未初始化,
*pa = 10;
return 0;
}
int main() {
int arr[10] = {
0 };
int* pa = arr;
int i = 0;
for (i = 0; i < 12; i++) {
pa++;
}
//指针越界
return 0;
}
int* test() {
int a = 10;
return &a;
}
int main() {
int* p = test();
*p = 0;
//指针已经释放了的空间进行访问
return 0;
}
指针变量记得初始化
小心控制,指针越界处理
释放空间后,对指针置NULL
指针使用之前检查其有效性
指针的运算
- 指针-+整数
- 指针-指针
- 指针的关系运算
int main() {
int arr[10] = {
1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = &arr[9];
for (i = 0; i < sz; i++) {
printf("%d ", *p);
p++;
}
//for (i = 0; i < 5; i++) {
// printf("%d ", *p);
// p-=2;
//}
return 0;
}
int main() {
int arr[5] = {
0,1,2,3,4 };
int* p = arr;
int* p2 = &arr[5];
int i = 0;
for (i = 0; i < p2 - p; i++) {
printf("%d ", i);
}
return 0;
}
int main() {
int arr[5] = {
0,1,2,3,4 };
int* p = arr;
int* p2 = &arr[5];
while (p2 > p) {
printf("%d ", *p);
p++;
}
return 0;
}
指针和数组
数组名就是首元素的地址
int main() {
int arr[10] = {
0 };
printf(" %p\n ", arr);
printf("%p\n ", arr+1);
printf("%p\n ", &arr[0]);
printf("%p\n ", &arr[0]+1);
printf("%p\n ", &arr);
printf("%p\n ", &arr+1);
return 0;
}
1.&arr -&数组名-不是取首元素的地址是取整个数组的地址-数组名表示整个数组
2.sizeof(arr)-sizeof(数组名)-是计算整个元素的大小-数组名表述整个数组的大小
int main() {
int arr[10] = {
0 };
int* pa = arr;
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//for (i = 0; i < sz; i++) {
// *(pa + i) = i;
//}
//for (i = 0; i < sz; i++) {
// printf("%d ", arr[i]);
//}
for (i = 0; i < sz; i++) {
arr[i] = i;
}
for (i = 0; i < sz; i++) {
printf("%d ", *(pa + i));
}
return 0;
}
二级指针
指针变量也是变量,是变量就有地址,那么指向指针地址的指针就叫做二级指针
int main() {
int a = 10;
int* pa = &a;
int** ppa = &pa;
int*** pppa = &ppa;
//...
printf("%d\n", **ppa);
printf("%d\n", a);
return 0;
}
输出结果相同
指针数组
指针数组就是存储指针的数组
int main() {
int a = 10;
int b = 20;
int c = 30;
//int* pa = &a;
//int* pb = &b;
//int* pc = &c;
//整形数组-存储整形
//字符数组-存储字符
//指针数组-存储指针
//int arr[3] = { 1,2,3 };
int* arr2[3] = {
&a,&b,&c };
int i = 0;
for (i = 0; i < 3; i++) {
printf("%d\n",*(arr2[i]));
}
return 0;
}
思想和代码一定要结合,一定不能只想不练,多用代码实现着理解。
边栏推荐
- Dark chain lock (lca+ difference on tree)
- What are the advantages of using SQL in Excel VBA
- [algorithm] sword finger offer2 golang interview question 2: binary addition
- Error: sorting and subscript out of bounds
- [算法] 剑指offer2 golang 面试题5:单词长度的最大乘积
- 架构师怎样绘制系统架构蓝图?
- KF UD分解之UD分解基础篇【1】
- [Chongqing Guangdong education] Shandong University College Physics reference materials
- 十分钟彻底掌握缓存击穿、缓存穿透、缓存雪崩
- GNSS positioning accuracy index calculation
猜你喜欢
《软件测试》习题答案:第一章
系统设计学习(三)Design Amazon‘s sales rank by category feature
121 distributed interview questions and answers
[algorithm] sword finger offer2 golang interview question 8: the shortest subarray with a sum greater than or equal to K
[算法] 劍指offer2 golang 面試題2:二進制加法
2年经验总结,告诉你如何做好项目管理
[算法] 剑指offer2 golang 面试题13:二维子矩阵的数字之和
第一人称视角的角色移动
[算法] 剑指offer2 golang 面试题3:前n个数字二进制形式中1的个数
Combination of fairygui check box and progress bar
随机推荐
十分钟彻底掌握缓存击穿、缓存穿透、缓存雪崩
KF UD分解之伪代码实现进阶篇【2】
第一人称视角的角色移动
What are the functions and features of helm or terrain
【无标题】
FairyGUI增益BUFF數值改變的顯示
Sharing ideas of on-chip transplantation based on rtklib source code
[算法] 剑指offer2 golang 面试题9:乘积小于k的子数组
面渣逆袭:Redis连环五十二问,三万字+八十图详解。
抗差估计在rtklib的pntpos函数(标准单点定位spp)中的c代码实现
341. Flatten nested list iterator
121道分布式面试题和答案
[algorithm] sword finger offer2 golang interview question 6: sum of two numbers in the sorting array
Agile development helps me
编辑距离(多源BFS)
Basic DOS commands
Realization of the code for calculating the mean square error of GPS Height Fitting
WSL common commands
地球围绕太阳转
Record: solution of 404 error of servlet accessing database in dynamic web project