济南网站建设 unzz,提供网站建设服务平台,怎么注册公司微信公众号,微网站开发平台系统软件目录 一、指针是什么 二、指针和指针类型 三、野指针 四、指针运算 五、指针和数组 六、二级指针 七、指针数组 一、指针是什么 指针就是内存地址#xff0c;指针变量是用来存放内存地址的变量#xff0c;在同一CPU构架下#xff0c;不同类型的指针变量所占用的存储单元长度… 目录 一、指针是什么 二、指针和指针类型 三、野指针 四、指针运算 五、指针和数组 六、二级指针 七、指针数组 一、指针是什么 指针就是内存地址指针变量是用来存放内存地址的变量在同一CPU构架下不同类型的指针变量所占用的存储单元长度是相同的而存放数据的变量因数据的类型不同所占用的存储空间长度也不同(指针本质就是地址) 我们可以这么理解: 1.指针是个变量存放内存单元的地址/内存编号 #include stdio.h
int main()
{int a 10;//在内存中开辟一块空间int* p a;//这里我们对变量a取出它的地址可以使用操作符。//将a的地址存放在p变量中p就是一个之指针变量。return 0;
} 总结指针就是变量用来存放地址的变量。 二、指针和指针类型
这里我们在讨论一下指针的类型是什么我们都知道变量有不同的类型整形浮点型等。那指针有没有类型呢 其实是有的。当有这样的代码时
int num 10;
p num;
要将numnum的地址保存到p中我们知道p就是一个指针变量那它的类型是怎样的呢 我们给指针变量相应的类型。 char *pc NULL;
int *pi NULL;
short *ps NULL;
long *pl NULL;
float *pf NULL;
double *pd NULL; 这里可以看到,指针的定义方式是:type * 。其实:char* 类型的指针是为了存放 char 类型变量的地址.short* 类型的指针是为了存放 short 类型变量的地址.int* 类型的指针是为了存放 int 类型变量的地址. 那指针类型的意义是什么 指针-整数 #include stdio.h
//演示实例
int main()
{int n 10;char* pc (char*)n;int* pi n;printf(%p\n, n);printf(%p\n, pc);printf(%p\n, pc 1);printf(%p\n, pi);printf(%p\n, pi 1);return 0;
} 总结指针的类型决定了指针向前或者向后走一步有多大距离。 指针解引用 int main()
{int n 0x11223344;char* pc (char*)n;int* pi n;*pc 0; //重点在调试的过程中观察内存的变化。*pi 0; //重点在调试的过程中观察内存的变化。return 0;
} 总结指针的类型决定了对指针解引用的时候有多大的权限能操作几个字节。 比如 char* 的指针解引用就只能访问一个字节而 int* 的指针的解引用就能访问四个字节。 三、野指针 概念野指针就是指针指向的位置是不可知的随机的、不正确的、没有明确限制的指针变量在定义时如果未初始化其值是随机的指针变量的值是别的变量的地址意味着指针指向了一个地址是不确定的变量此时去解引用就是去访问了一个不确定的地址所以结果是不可知的。 野指针成因 1. 指针未初始化 #include stdio.h
int main()
{ int *p;//局部变量指针未初始化默认为随机值*p 20;return 0;
} 2. 指针越界访问 #include stdio.h
int main()
{int arr[10] {0};int *p arr;int i 0;for(i0; i11; i){//当指针指向的范围超出数组arr的范围时p就是野指针*(p) i;}return 0;
} 3. 指针指向的空间释放 这里放在动态内存开辟的时候讲解这里可以简单提示一下。 如何规避野指针 1. 指针初始化 2. 小心指针越界 3. 指针指向空间释放即使置NULL 4. 指针使用之前检查有效性 #include stdio.h
int main()
{int *p NULL;//....int a 10;p a;if(p ! NULL){*p 20;}return 0;
} 四、指针运算 • 指针- 整数 • 指针-指针 • 指针的关系运算 指针- 整数 #define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针-整数指针的关系运算
for (vp values[0]; vp values[N_VALUES];)
{*vp 0;
} 指针-指针 int my_strlen(char *s)
{char *p s;while(*p ! \0 )p;return p-s;
}
for(vp values[N_VALUES]; vp values[0];)
{*--vp 0;
}指针的关系运算 for(vp values[N_VALUES]; vp values[0];)
{*--vp 0;
}代码简化, 这将代码修改如下 for(vp values[N_VALUES-1]; vp values[0];vp--)
{*vp 0;
} 实际在绝大部分的编译器上是可以顺利完成任务的然而我们还是应该避免这样写因为标准并不保证它可行。 标准规定 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 五、指针和数组 数组名是什么我们看一个例子 #include stdio.h
int main()
{int arr[10] {1,2,3,4,5,6,7,8,9,0};printf(%p\n, arr);printf(%p\n, arr[0]);return 0;
} 运行结果: 可见数组名和数组首元素的地址是一样的。 结论数组名表示的是数组首元素的地址。 那么这样写代码是可行的 int arr[10] {1,2,3,4,5,6,7,8,9,0};
int *p arr;//p存放的是数组首元素的地址 既然可以把数组名当成地址存放到一个指针中我们使用指针来访问一个就成为可能。 例如 #include stdio.h
int main()
{int arr[] {1,2,3,4,5,6,7,8,9,0};int *p arr; //指针存放数组首元素的地址int sz sizeof(arr)/sizeof(arr[0]);for(i0; isz; i){printf(arr[%d] %p p%d %p\n, i, arr[i], i, pi);}return 0;
} 运行结果: 六、二级指针 指针变量也是变量是变量就有地址那指针变量的地址存放在哪里这就是 二级指针 。 对于二级指针的运算有 *ppa 通过对ppa中的地址进行解引用这样找到的是 pa *ppa 其实访问的就是 pa int b 20;
*ppa b;//等价于 pa b; **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作 *pa 那找到的是 a **ppa 30;
//等价于*pa 30;
//等价于a 30;
int arr1[5];
char arr2[6];七、指针数组 1.指针数组是指针还是数组 答案是数组。是存放指针的数组。 2.数组我们已经知道整形数组字符数组。 那指针数组是怎样的 int* arr3[5]; arr3是一个数组有五个元素每个元素是一个整形指针