**学习无止境**记录学习
目录
目录
一、指针是什么?
1.指针是内存中最小单元的编号,也就是地址
2.平时口语中所说的指针,通常指的是的指针变量,用来存放内存地址的变量
- 指针变量:我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量。
-
#include<stdio.h> int main() { int a=10;//在内存中开辟一块空间 int*p=&a;//这里我们对变量a,取出他的地址,可以使用&操作符 //a变量占用4个字节的空间,这里将a的4个字节的地址存放p变量中,p就是一个指针变量 return 0; }
总结:指针变量,用来存放地址的变量。
-
一个小的单元:一个字节
-
指针的大小在 32 位平台是 4 个字节,在 64 位平台是 8 个字节 。
二、指针和指针类型
我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?
准确的说:有的。
1.指针+-整数
代码如下(示例):
总结:
指针的类型决定了指针向前或者向后走一步有多大(距离)。
2.指针的解引用
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:
char*
的指针解引用就只能访问一个字节,而
int*
的指针的解引用就能访问四个字节。
3.野指针
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
- 野指针成因:指针未初始化
- 指针越界访问
#include <stdio.h> intmain() { int arr[10] = {0}; int * p=arr; int i=0; for(i=0; i<=11; i++) { //当指针指向的范围超出数组arr的范围时,p就是野指针 *(p++) =i; } return0;
- 指针指向的空间释放
4.规避野指针
1.
指针初始化
2.
小心指针越界
3.
指针指向空间释放即使置
NULL
4.
避免返回局部变量的地址
5.
指针使用之前检查有效性
5.指针运算
1.指针的加减运算
指针是地址,地址是无符号的整数。但指针却不能像整数那样参与乘法和除法。因为对指针乘以或除以一个数没有意义。
定义:ptype*p,并且p当前的值是ADDR,那么
p+-n的值=ADDR+-n*sizeof(ptype)
注意:两个指针相加没有任何意义,但两个指针相减则有一定的意义,可表示两指针所相差的内存单元或元素的个数。
2.指针变量的关系运算
两个指针变量进行关系运算可表示它们所指向的内存单元之间的关系。例如,假设p1和p2是两个指针变量。
- p1==p2表示p1和p2指向同一内存单元
- p1>p2表示p1处于高地址位置
- p1<p2表示p1处于低地址位置
- 指针变量还可以与0比较
6.指针和数组
结论:数组名表示是数组首元素的地址。
p+i
其实计算的是数组
arr
下标为
i
的地址。
那我们就可以直接通过指针来访问数组。
如下:
7.二级指针
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
这就是
二级指针
。
#include<stdio.h>
int main()
{
int a=10;
int *pa=&a;//pa是指针变量,一级指针
//ppa就是一个二级指针
int **ppa=&pa;//pa也是个变量,&pa取出pa在内存中的起始位置
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;
8.指针数组
指针数组是指针还是数组?
答案:是数组。是存放指针的数组。
数组我们已经知道整形数组,字符数组
int arr1[5];//整型数组,存放整型的数组就是整型数组
char arr2[6];//字符数组,存放的是字符
int* arr3[5];//指针数组,存放的是指针