当前位置:网站首页>初识指针笔记
初识指针笔记
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;
}
思想和代码一定要结合,一定不能只想不练,多用代码实现着理解。
边栏推荐
- Exception: ioexception:stream closed
- [Chongqing Guangdong education] reference materials for regional analysis and planning of Pingdingshan University
- Implementation of Excel import and export functions
- [算法] 剑指offer2 golang 面试题1:整数除法
- [GNSS] robust estimation (robust estimation) principle and program implementation
- 基本Dos命令
- [algorithm] sword finger offer2 golang interview question 9: subarray with product less than k
- wsl常用命令
- [算法] 剑指offer2 golang 面试题2:二进制加法
- How to improve the deletion speed of sequential class containers?
猜你喜欢
基本Dos命令
Combination of fairygui check box and progress bar
[algorithm] sword finger offer2 golang interview question 4: numbers that appear only once
Detailed explanation of balanced binary tree is easy to understand
阿里云微服务(四) Service Mesh综述以及实例Istio
Fairygui character status Popup
Prove the time complexity of heap sorting
Redis介绍与使用
系统设计学习(三)Design Amazon‘s sales rank by category feature
[算法] 劍指offer2 golang 面試題2:二進制加法
随机推荐
[algorithm] sword finger offer2 golang interview question 8: the shortest subarray with a sum greater than or equal to K
FairyGUI循環列錶
【干货】提升RTK模糊度固定率的建议之周跳探测
MySQL backup -- common errors in xtrabackup backup
[dry goods] cycle slip detection of suggestions to improve the fixed rate of RTK ambiguity
Rt-ppp test using rtknavi
Wechat applet development experience
Knowledge system of digital IT practitioners | software development methods -- agile
《软件测试》习题答案:第一章
KF UD分解之UD分解基础篇【1】
How to ensure data consistency between MySQL and redis?
[algorithm] sword finger offer2 golang interview question 5: maximum product of word length
All in one 1405: sum and product of prime numbers
[算法] 剑指offer2 golang 面试题7:数组中和为0的3个数字
Record: the solution of MySQL denial of access when CMD starts for the first time
Fairygui character status Popup
Detailed explanation of balanced binary tree is easy to understand
Record: I accidentally wrote a recursion next time
10 minutes pour maîtriser complètement la rupture du cache, la pénétration du cache, l'avalanche du cache
[algorithm] sword finger offer2 golang interview question 12: the sum of the left and right sub arrays is equal