初识指针
在32位的平台上,指针类型都是占4个字节,都能存32个bit位,指针为什么要区分类型呢,
例1:
Int a=0x11223344;
Int* pa = &a;
*pa=0;
此处的*pa操作了32个bit位对a进行了清零
例2:
Int a=0x11223344;
char* pa = &a;
*pa=0;
此处的*pa操作了8个bit位00223344
指针类型在解引用操作的时候决定了能够操作空间的大小
当我是int*的时候能够操作4个字节
当我是char*的时候能够操作1个字节
当我是double*的时候能够操作8个字节
怎么申请空间:
Int* test()
{
Int a=10;
Return &a;
}
Int main()
{
Int* p = test();
Printf(“%d”,*p);
}
注意:这个代码有很严重的错误,当我们调用test函数的时候,进到函数里面,首先a是一个局部变量,局部变量作用域只在函数内,局部变量进入到函数里面就创建,出函数就销毁了,相当于内存就释放了,这里return返回的地址其实出函数的时候就已经释放掉了,下面在对p地址进行访问的时候其实就是访问到了一个非法的地址,因为地址出函数已经被释放掉了。
怎么避免野指针:
- 再进行使用的时候一定要进行初始化
- 在进行指针访问的时候不要出现越界,特别是在进行数组访问的时候
- 或者赋空指针NULL 例:int* p = NULL;//NULL-用来初始化指针的,给指针赋值,等价于int=0;
- 指针指向空间,如果空间已经释放了,还想要这片空间合法的存在,就先初始化为空指针
例:int a = 10; int* pa=&a; *pa = 20;pa = NULL;这个时候pa就已经没有指向a的地址了;
5、使用指针的时候先检查指针的有效性
例:if(pa != NULL)
{
}
如何用指针访问数组元素:
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int* pb = arr;
int i;
for (i = 0; i < 10; i++)
{
printf("%d\n", *(pb + i));
}
return 0;
}
这里很多人会问数组名不是数组首元素的地址吗,为什么不能直接进行运算呢,因为数组名不是一个左值所以不能参与运算。
例:求字符串长度
int strlen_l(char* pb)
{
int count = 0;
while (*(pb++) != '\0')
{
count++;
}
return count;
}
int main()
{
char arr[] = "abc";
int sz = strlen_l(arr);
printf("%d\n", sz);
return 0;
}
指针的关系运算:
#define N_VALUES 5
float values[N_VALUES];
flaot* vp;
for (vp = &values[N_VALUES]; vp > &values[0];) //地址是由高到低的,这里对地址进行比较,vp首先拿到的是values第五个元素的地址,每一次进入循环都对values元素赋一个新值0;
{
*--vp = 0; //这里的vp先与—进行结合地址-1在进行解引用赋值
}
指针与数组:
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr); //数组名就是首元素地址
printf("%p\n", &arr[0]); //这里都是取首元素地址
//除非两种情况
/*1、&arr这是取出整个数组的地址*/
/*2、在进行sizeof运算的时候 sizeof(arr)此时是计算整个数组的大小,单位是BYTE,数组名表示整个数组*/
return 0;
}
二级指针:
int main()
{
int a = 10;
int* pa = &a; //一级指针
int** ppa = &pa; //二级指针
int*** pppa = &ppa; //三级指针
printf("%p\n", *pppa);/*这里*pppa进行解引用打印的就是ppa的地址*ppa指针指向的是一个二级指针*/
printf("%p\n", ppa);
return 0;
}
/*二级指针的变量只是存放了一级指针的地址而已*/
指针数组:
指针数组是数组-、数组里面每一个元素都是一个指针变量;
int main()
{
int a = 10;
int b = 20;
int c = 30;
int i;
//int* pa = &a;
//int* pb = &b;
//int* pc = &c;
int* arr[10] = { &a,&b,&c };/*指针数组,里面每一个元素都是一个整形指针变量*/
for (i = 0; i < 3; i++)
{
printf("%d\n", **(arr+i));
}
return 0;
}
/*这里在进行解引用的时候arr是首元素的地址,*arr就指向了a的地址,**arr就访问到了a里面的值,其实这里就相当于一个二级指针的访问形式:
也可以这样访问:
printf("%d\n", *arr[0]);
printf("%p\n", *arr[1]);
这样就通过对元素进行解引用操作访问到了指针变量的值
*/