前言
指针是C语言学习阶段的一个难点,本文将介绍C语言中的指针,什么是指针,指针类型以及指针运算等相关内容。
一、指针
1.什么是指针
对指针可以做出以下理解: 指针是个变量,用来存放内存单元的地址
即指针是一种保存变量地址的变量。
整个过程对应到C代码中如下:
#include <stdio.h>
int main()
{
//定义int 类型变量 a,并初始化值为:10
int a = 10;
int *p = &a; //(1)对变量a,使用&符号取出它的地址
//(2)在将a的地址存放在p变量中
return 0;
}
对应图解如下:
2.指针类型
指针类型:指针声明语句里除指针名之外的部分就是这个指针的类型。
有如下代码:
int *p; //指针的类型是int*
char *p //指针的类型是char*
int *arr[10] //指针的类型是int* [10]
int (*arr)[10] //指针的类型是int (* )[10]
int **p; //指针的类型是int **
可以看到,指针的类型有很多种,那么不同指针类型有什么作用呢?
3.指针类型的作用
先看以下实例:
#include <stdio.h>
int main()
{
int n = 10;
char* p1 = (char*)&n; //n为整型数据,将其强制转换为(char*)
int* p2 = &n;
printf("%p\n", &n);
printf("%p\n", p1);
printf("%p\n", p1 + 1);
printf("%p\n", p2);
printf("%p\n", p2 + 1);
return 0;
}
对应图解如下:
可以得出结论:指针的类型决定了指针向前或者向后走一步有多大(距离)
补充: 前面已经提到内存其实就是一组有序字节组成的数组。其存储数据最小单位是字节。
4.指针解引用
学习指针离不开 * 符号。
指针比普通变量的声明多了一个一元运算符 “ * ”
int a=10;
int * p=&n ;
“*” :间接引用(间接寻址)运算符。 当它作用于指针时,将访问指针所指向的对象。
例:
#include <stdio.h>
int main()
{
int n = 10;
int* p = &n;
printf("%d", *p);
return 0;
}
代码运行结果如下:
注意:: 指针类型还决定了对指针解引用的时候有多大的权限(能操作几个字节)。 例: char 指针解引用就只能访问一个字节*,而 int*指针的解引用就能访问四个字节。
二、野指针
1.指针声明
声明一个指针变量:
//(1)直接声明
int * p;
//(2)声明并初始化
int a=10;
int *p=&a;
值得注意的是:第一种方式程序会直接报错。
指针在声明时并不会自动分配任何内存。在对指针进行间接访问之前,指针必须进行初始化。 否则指针随机指向。
2.什么是野指针?
野指针: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
3.产生野指针的原因
(1) 指针未初始化
例:
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
printf("%d",*p);
return 0;
}
运行结果出错:
(2)指针越界访问
例:
#include <stdio.h>
int main()
{
int a[10] = {0};
int *p = a;//数组名即为该数组首元素的地址
for(int i=0; i<=11; i++)
{
//当指针指向的范围超出数组a的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
程序运行出错!
因此在使用指针时要注意:a.指针初始化 b.注意指针越界 c. 指针使用之前检查有效性
例如:
#include <stdio.h>
int main()
{
int a = 10;
p = &a;
if(p != NULL) //检查有效性
{
*p = 20;
}
return 0;
}
三、指针和数组
1.数组名
我们先来看以下这个例子:
#include <stdio.h>
int main()
{
int a[10] = {1,2,3,4,5};
printf("%p\n", a);
printf("%p\n", &a[0]);
return 0;
}
图解如下:
结论:数组名表示的是数组首元素的地址。
2.实例代码
因此:以下代码成立:
int a[5] = {1,2,3,4,5};
int* p=a;
实例如下:
#include <stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
int* p = arr; //指针存放数组首元素的地址
for (int i = 0; i < 5; i++)
{
printf("对数组中的第 %d 元素取地址:&arr[%d] = %p p+%d = %p\n",i, i, &arr[i], i, p + i);
}
return 0;
}
运行结果:
以上代码可以写成如下形式:
#include <stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
int* p = arr;
for (int i = 0; i < 5; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
for (int i = 0; i < 5; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
运行结果如下:
总结
提示:以上就是本文的全部内容。