三好街做网站的公司,网上网站开发,网站开发登录链接,图片外链在线生成网址一.指针基本概念#xff1a;
指针是内存中一个最小单元的编号#xff0c;也就是地址平时口语中说的指针#xff0c;通常指的是指针变量#xff0c;是用来存放地址的变量 #includestdio.h
int main()
{int a 0;//a是整型变量#xff0c;占用四个字节的内存空间
指针是内存中一个最小单元的编号也就是地址平时口语中说的指针通常指的是指针变量是用来存放地址的变量 #includestdio.h
int main()
{int a 0;//a是整型变量占用四个字节的内存空间在内存中开辟一块空间int* pa a;printf(%p, pa);//pa是一个指针变量用来存放地址这里是将a的四个字节的第一个字节的地址存放在ap变量中return 0;
} 指针变量我们可以通过取地址操作符取出变量的内存真实地址把地址可以存放到一个变量中这个变量就是指针变量。存放在指针中的值都被当成地址处理指针变量中存放的是地址通过这个地址就可以找到一个内存单元指针的大小在32位平台是四个字节在64位平台是八个字节 x86 - 32位 x64 - 64位 二.指针和指针类型
我们都知道普通变量都有不同的类型由整型字符型浮点型等等而指针变量也有不同的类型 int a 5;假设有以上a变量那么我们可以将a的地址储存进以下指针变量中char* pc a;short* ps a;int* pi a;long* pl a;float* pf a;double* pd a;我们需要注意的是例如int*p——指针类型是int*指针所指向的类型是int。不要记混既然一个整型类型的数据可以被别的不同类型数据的指针储存那么指针类型的意义又是什么呢 1指针-整数
总结指针的类型决定了指针向前或向后走一步有多大距离 2指针的解引用
#includestdio.h
int main()
{int n 0x11223344;char* pc (char*)n;int* pi n;*pc 0;//重点在调试的过程中观察内存的变化*pi 0;//重点在调试的过程中观察内存的变化return 0;
}
总结指针类型决定了对指针解引用的时候有多大权限能操作几个字节。
比如 char* 的指针解引用就只能访问一个字节而 int* 的指针解引用就能访问四个字节 三.野指针 概念野指针就是指针指向位置是不可知的随机的不正确的没有明确限制的 1野指针成因
指针未初始化 #includestdio.h
int main()
{int* p;//p没有初始化就意味着没有明确的指向//一个局部变量不初始化的话放的是随机值*p 10;//非法访问内存了return 0;
} 指针越界访问 #includestdio.h
int main()
{int arr[10] { 0 };int* p arr;int i 0;for (i 0; i 11; i){//当指针范围超出数组arr的范围时p就是野指针*(p) i;}return 0;
} 指针指向的空间释放 #includestdio.h
int* test()
{int a 10;//a为局部变量函数开始时创建函数结束时销毁return a;
}
int main()
{int* p test();*p 20;//此时p指向的空间已销毁被释放不属于当前程序,此时指针p就为野指针return 0;
}2如何规避野指针 指针初始化注意指针是否越界指针指向被释放空间时置为NULL空指针指针使用之前应检查其有效性 这里展示几个代码
比较以下代码并注意注释的内容 函数栈帧与销毁 四.指针运算
1指针-整数
总结
从0位到5位地址是由低到高的*p0;相当于*p0 p 指针变量的自增自减运算指针加一或减一运算表示指针向前或向后移动一个单位不同类型的指针单元长度不同 。这个在数组中非常常用。 #includestdio.h
int main()
{int arr[10] { 0 };int i 0;int n sizeof(arr) / sizeof(arr[0]);//计算出数组中元素的个数/*for (i 0; i n; i){arr[i] 1;}*/int* p arr[0];for (i 0; i n; i){*p 1;//*(pi)1}return 0;
}
2指针-指针
观察下图
可以很直观的得出数组中两个指针相减得到的是指针和指针之间元素的个数 注意 不是所有指针都能相减指向同一块空间的两个指针才能相减 例题编写函数不允许创建临时变量求字符串的长度三种方法
循环递归指针-指针
//循环
#includestdio.h
int my_strlen(char* n)
{int count 0;while (*n ! \0){count;n;}return count;
}
int main()
{int len my_strlen(lover);printf(%d, len);return 0;
}
//递归
#includestdio.h从
int my_strlen(char* n)
{if (*n ! \0){return 1 my_strlen(n 1);}else{return 0;}
}
int main()
{int len my_strlen(lover);printf(%d, len);return 0;
}//指针-指针
#define _CRT_SECURE_NO_WARNINGS
#include stdio.h
int my_strlen(char* n)
{char* np n;while (*n ! \0){n;}return n - np;
}
int main()
{char arr[] study;int len my_strlen(arr);printf(%d, len);return 0;
} 3指针的关系运算
#includestdio.h
#define A 5
int main()
{int arr[10] { 0 };int* p arr[A];for (p arr[A]; p arr[0];){*--p 0;}return 0;
}
标准规定允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 五.指针和数组 数组名表示的是数组首元素地址两种情况除外数组章节讲了——sizeof 不必多说数组那节都已经讲了 六.二级指针 二级指针变量用来存放一级指针变量的地址 观察下面代码
pa是一个指针变量一级指针ppa是一个二级指针变量int*是说明ppa是指针ppa指向的对象是int*类型 七.指针数组 指针数组是数组是存放指针的数组数组我们已经了解了整型数组字符数组 观察下列代码
#includestdio.h
int main()
{int a 10;int b 20;int c 30;int arr[10];int* ap a;int* bp b;int* cp c;//parr是存放指针的数组就是指针数组int* parr[10] { a,b,c };int i 0;for (i 0; i 3; i){printf(%d\n, *(parr[i]));}return 0;
}
可以用其打印二维数组
#includestdio.h
int main()
{int arr1[4] { 1,2,3,4 };int arr2[4] { 2,3,4,5 };int arr3[4] { 3,4,5,6 };int* parr[3] { arr1,arr2,arr3 };int i 0;for (i 0; i 3; i){int j 0;for (j 0; j 4; j){printf(%d, parr[i][j]);//相当于arri[j]//parr[1]相当于arr1也可以改为 *( *(parri)j)//arr[i] *(arri)printf(\n);}return 0;
}
知识点arr[i] *(arri)