初识C语言-指针初级(1)
指针是C语言重要的一部分,学好指针是非常重要的,通过本篇博客先对指针有大致的认识,以便为后续的指针进阶打下基础。
1.指针的概念
首先,指针是什么? 1.指针是内存中一个最小单元的编号,也就是地址 2.指针,简单来说就是我们创建一个变量,内存会为变量分配内存空间,而指针就是用来存放内存地址的变量。指针通常指的是指针变量。
int a = 10;//在内存中开辟一块空间
int* p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个之指针变量。
// *表示这是一个指针变量,指针指向的a为int类型,所以是int类型的指针,写作int*`
如上图代码块所示,我们可以得出:指针变量,用来存放地址的变量。
2.指针的大小
1.指针的大小根据机器位数而发生变化,在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。 2.得出:指针大小在32位平台是4个字节,在64位平台是8个字节。
3.指针和指针类型
我们知道,数据有整形,浮点型等等,那么指针也会有相应的数据类型。
char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
/*我们创建了各种类型的指针,
char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。*/
那么这些不同类型指针有什么用呢? 如上图所示,int类型指针可以操作4个字节。
上图所示,将指针类型从Int改为char,只能操作一个字节。
指针类型的意义 1.指针类型决定了:指针解引用的权限有多大 2.指针类型决定了指针走一步走多远(步长)
4.野指针
4.1野指针的概念
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
4.2野指针的成因
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(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
3、指针指向的空间释放
4.3如何避免野指针的出现
- 指针初始化
- 小心指针越界
- 指针指向空间释放,及时置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
#include <stdio.h>
int main()
{
int *p = NULL;
int a = 10;
p = &a;
if(p != NULL)
{
*p = 20;
}
return 0;
}
5.指针的运算
5.1 指针± 整数
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
//将数组的值都置为0
5.2 指针-指针
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}
//指针相减求的是指针之间的元素个数,但是要注意两个指针一定要指向同一个内存空间
5.3 指针的关系运算
#define N_VALUES 5
for(vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}
//将上述代码简化
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
//标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。
6.指针和数组
在之前的博客中,我们知道了数组名就是首元素的地址,由上图所示,两者的地址是一模一样的,因此我们可以使用指针保存数组的地址,从而实现对数组的访问。
nt main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i<sz; i++){
printf("%d ", *(p + i));
}
return 0;
}
arr是数组名为首元素地址,p也是地址指向数组,由此arr=p,我们将他们互相替换,就如上图所示,由此指针的使用是非常灵活的。
7.二级指针
指针是存放地址的变量,那指针本身也是一个变量,也可以通过指针来保存他的地址,这就是二级指针。
|