目录:
一.定义:指针是内存中一个最小单元的编号,也就是地址。
指针变量: 我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个 变量就是指针变量。
一般我们所说的指针约等于指针变量。
注意:一般内存就是4/8/16g的,最小的单元是一个字节,指针变量用于存放变量的地址,32位机器就是4字节,64则是8字节。
二.一级指针和指针类型
1.指针一般的创建和使用:(例子)
int main()
{int a=0//创建变量
int*p=&a;//创建指针变量
*p=100;//解引用,并对a重新赋值
printf("%d",*p)//打印重新赋值后的a的值
printf("%p",*p)//打印a的地址//一般打印出来是16进制,会有0-9,abcdef(分别代表10,11,12,13,
//14,15)
return 0;
}
总结:1.创建:数据类型+*变量名=&变量;2.使用:用于对以前的不易找到的变量的操作(方便)
2. 指针+-整数(%p用于打印指针)
证明和数据类型有关,int+4 ,char+1,则long long +8;也就是+数据类型占字节*(指针加的数子)
与以上比较证明其中b,d为指针变量,打印指针直接写就行,但要是打印其存地址数据则用*(变量),因为要解引用才能用。
注意:对于一维数组有些许不同在于,不用写&,原因在于数组名代表首位元素的地址。但是使用时无妨;
3.指针+—指针
用于同一数组,相减等于其中间元素个数;
三.野指针
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的);
1类型: (1)未初始化
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(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
2.如何减少野指针出现次数
1. 指针初始化 2. 小心指针越界 3. 指针指向空间释放,及时置NULL 4. 避免返回局部变量的地址
四.指针和数组
联系:数组名表示的是数组首元素的地址。(有两个除外sizeof(arr)求得是整个数组长度,&数组名取出的是整个数组)区别:指针是地址占4/8个字节,数组是同类数据的集合。
五.二级数组。
定义:指针变量也是变量,是变量就有地址,那指针变量的地址存放在二级指针。(也就是指针的指针)
int a=0;
int*pa=&a;
int**ppa=&pa;
printf("%d",**ppa)//结果是a变量的数据
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;
六.指针数组。
定义:存放数组地址的数组(是数组)。
用法:用于储存一系列相同类型的数组。
可以用一维数组充当二维数组。
void copy1(int **pa)
{
int c = 0, d = 0, e = 0;
for (c = 0; c < 3; c++)
{
d = 0; printf("\n");
for (d = 0; d < 3; d++)
{
printf("%d\t", *((int*)(*(pa+c))+d));
}
}
}
int main()
{
int arr[] = { 1,2,3 };
int arr2[] = { 4,5,6 };
int arr3[] = { 7,8,9 };
int* a[3] = {arr,arr2,arr3 };
copy1((int**)a);
return 0;
}