当前位置:网站首页>初识指针笔记
初识指针笔记
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;
}
思想和代码一定要结合,一定不能只想不练,多用代码实现着理解。
边栏推荐
- How to improve the deletion speed of sequential class containers?
- Lean product development - Lean Software Development & lean product development
- 【干货】提升RTK模糊度固定率的建议之周跳探测
- [algorithm] sword finger offer2 golang interview question 8: the shortest subarray with a sum greater than or equal to K
- 阿里云微服务(一)服务注册中心Nacos以及REST Template和Feign Client
- Pride-pppar source code analysis
- rtklib单点定位spp使用抗差估计遇到的问题及解决
- [算法] 剑指offer2 golang 面试题10:和为k的子数组
- FairyGUI循環列錶
- 记录:newInstance()过时的代替方法
猜你喜欢

Record: the solution of MySQL denial of access when CMD starts for the first time

2年经验总结,告诉你如何做好项目管理

The service robots that have been hyped by capital and the Winter Olympics are not just a flash in the pan
![[算法] 剑指offer2 golang 面试题13:二维子矩阵的数字之和](/img/17/e7c9bfa867030af97eb66a7932c7e3.png)
[算法] 剑指offer2 golang 面试题13:二维子矩阵的数字之和
![[algorithm] sword finger offer2 golang interview question 6: sum of two numbers in the sorting array](/img/d5/4bda133498f71ae9fd7a64c6cba8f0.png)
[algorithm] sword finger offer2 golang interview question 6: sum of two numbers in the sorting array

MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列

3月15号 Go 1.18 正式版发布 了解最新特色以及使用方法

系统设计学习(二)Design a key-value cache to save the results of the most recent web server queries

Detailed explanation of balanced binary tree is easy to understand
![[algorithm] sword finger offer2 golang interview question 2: binary addition](/img/c2/6f6c3bd4d70252ba73addad6a3a9c1.png)
[algorithm] sword finger offer2 golang interview question 2: binary addition
随机推荐
[untitled]
WSL common commands
RTKLIB: demo5 b34f.1 vs b33
Pride-pppar source code analysis
KF UD decomposition pseudo code implementation advanced [2]
【rtklib】在rtk下使用抗差自适应卡尔曼滤波初步实践
[算法] 剑指offer2 golang 面试题6:排序数组中的两个数字之和
[algorithm] sword finger offer2 golang interview question 13: sum of numbers of two-dimensional submatrix
XV Function definition and call
阿里云微服务(二) 分布式服务配置中心以及Nacos的使用场景及实现介绍
The earth revolves around the sun
异常:IOException:Stream Closed
最短Hamilton路径 (状压DP)
雇佣收银员【差分约束】
[rtklib] preliminary practice of using robust adaptive Kalman filter under RTK
[algorithm] sword finger offer2 golang interview question 3: the number of 1 in the binary form of the first n numbers
堆排序【手写小根堆】
微信小程序开发心得
Iterable、Collection、List 的常见方法签名以及含义
Error: symbol not found