C语言知识点之 指针1

导言

今天分享一些C语言指针的基础知识

1.指针是什么

a

指针是内存中最小单元的编号,也叫做地址

b

指针通常指的是指针变量,是用来存放地址的变量

注意:
存放在指针变量里的数值,在处理时默认是地址

概念辨析:

a

内存被划分为很多内存单元,每个内存单元大小是一个字节

b

每个字节的内存单元都有一个唯一的编号

c

地址是不需要存储起来的,如果要存储的话,要放在指针变量里。
在32位机器中,地址大小是(32个bit位)4个字节,所以指针的大小也是4个字节
在64位机器中,则是8个字节(64个bit位)

2.指针和指针类型

即然在同一个机器下地址大小是固定的,那么为什么还要有不同类型的指针呢

作用a:

下面给出一组对比
C语言知识点之 指针1_第1张图片
C语言知识点之 指针1_第2张图片

由此可以看出:
指针类型决定了指针进行解引用操作的时候,访问几个字节。
int* 访问四个字节
char*访问一个字节

区别b :

给出另一组对比

C语言知识点之 指针1_第3张图片

在进行运算时,都是+1
char*,只增加1个字节
int*则会增加4个字节

由此可以看出,其增加的是其类型的字节大小。
所以,要达到相同的目的,不同的指针类型所需要的次数也不同

3.野指针

指针指向的位置是不可知的,即其指向的不是自己

3.1野指针成因

a 指针未初始化
int *p;//直接报错
b 指针越界访问
c 指针的空间被释放
C语言知识点之 指针1_第4张图片

简单解释一下:
尽管p在函数中接收了a的地址,但a这个临时变量其在内存中申请的空间已经随着函数的结束而销毁了,所以p就是一个野指针

3.2避免形成野指针

a 指针初始化

如果明确知道指针指向的对象,那就初始化地址即可
如果指针不知道初始化什么值,为了安全,此时可以将其初始化为NULL(空指针),用这个方法可以处理3.1.c的问题

注意:
地址是NULL(0)时,是无法访问的

b 小心指针越界

c 避免返回局部变量的地址

d 指针使用之前要检查其有效性

4.指针运算

4.1指针与整数

可以参考2.b的运算

提示:

[]仅仅是操作符:
所以arr[i] == i[arr]
因为在编译时,上面两个表达式都会转换为*(arr+i),并且数组在内存中的存储是连续的

4.2指针与指针

指针-指针的前提:
两个指针指向同一块区域。
其差值的绝对值是他们之间的元素个数

应用:模拟strlen求字符串长度

#include

size_t my_strlen(char* str)
{
	char* start = str;
	while (*str)//当str解引用后不是“\0”的时候,就一直循环
	{
		str++;
	}
	return str - start;
}

int main()
{
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

4.3指针的关系运算

请观察下面在for循环中两种指针的关系运算
代码1:

#define VA 5
float values[VA];
float* vp;
int main()
{
	for (vp = &values[0]; vp < &values[VA];)
	{
		*vp++ = 0;
	}
}

代码2:

#define VA 5
float values[VA];
float* vp;
int main()
{
	for (vp = &values[VA]; vp > &values[0];)
	{
		*--vp = 0;
	}
}

代码1中,是从低地址向高地址,是用低地址与高地址比较
代码2中,是从高地址向低地址,是用高地址与低地址比较
如图:
C语言知识点之 指针1_第5张图片

注意:
在代码2中,有人想进行简化,如下:

for (vp = &values[VA-1]; vp >= &values[0]; vp--)
{
	*vp = 0;
}

但这么简化并不好,原因如下
标准规定:允许指向数组元素的指针与指向数组最后一个元素的那个内存位置的指针进行比较,但,不允许与只想第一个元素之前的那个内存位置的指针进行比较。
当运行到vp==-1时,在条件判断部分,他便是第一个元素之前的那个内存位置的指针,所以在某些情况下,这是不被允许的
(了解即可)

(在C++中,创建数组,会在数组首元素的前一个地址开辟一个空间,用于系统维护这个数组,但实际上数组返回的是其首元素)

5.指针和数组

概念辨析:
指针就是指针,指针变量就是一个变量,存放的地址,指针变量的大小是4/8
数组就是数组,可以存放一组数,数组的大小是取决于元素的类型和个数

二者关系:
数组的数组名是数组首元素的地址,其地址是可以存储指针变量中。
通过指针可以访问这个数组的元素。

注意:

&数组名:
表示的是数组的地址,虽然在数值上,数组的地址和数组首元素的地址相同,但二者的意义和类型都不同

区别是:在与整数进行运算时,其跳过的字节数不同

6.二级指针

存放一级指针变量的地址的变量,定义为二级指针变量
比如:
int ** pp = &p
其解引用时,所需的操作符也是两个

C语言知识点之 指针1_第6张图片

提示:

对于二级指针pp类型的补充说明:
后面的那个星号(此处打不出来那个符号)是在说明pp是指针变量
而int*是在说明pp所指向的变量类型是整型指针

7.指针数组

定义:存放指针的数组

概念辨析拓展:

此处可以看我另一篇文章中的第二题中的概念辨析
点击此处跳转

结语

对于指针的初步介绍就到这里了,我们下次再见。

你可能感兴趣的:(C语言知识点,c语言,开发语言)