C语言知识点之 指针1

导言

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

1.指针是什么

a

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

b

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

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

概念辨析:

a

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

b

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

c

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

2.指针和指针类型

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

作用a:

下面给出一组对比
在这里插入图片描述
在这里插入图片描述

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

区别b :

给出另一组对比

在这里插入图片描述

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

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

3.野指针

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

3.1野指针成因

a 指针未初始化
int *p;//直接报错
b 指针越界访问
c 指针的空间被释放
在这里插入图片描述

简单解释一下:
尽管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<stdio.h>

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中,是从高地址向低地址,是用高地址与低地址比较
如图:
在这里插入图片描述

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

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

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

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

5.指针和数组

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

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

注意:

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

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

6.二级指针

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

提示:

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

7.指针数组

定义:存放指针的数组

概念辨析拓展:

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

结语

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

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言指针的基础知识点: 1.指针的定义和初始化 指针是一个变量,其值为另一个变量的地址。定义指针变量时需要指定指针所指向的变量类型,然后使用*运算符来声明指针变量。指针变量的初始化可以为其赋值为另一个变量的地址,也可以将其初始化为NULL。 2.指针的运算 指针可以进行加、减、自增、自减等运算。指针加上一个整数n时,指向的地址会增加n个存储单元的大小,减去一个整数n时,指向的地址会减少n个存储单元的大小。 3.指针的比较 指针可以进行相等、大于、小于等比较运算。当两个指针指向同一个变量时,它们相等;当两个指针指向同一数组中的不同元素时,它们可以进行大小比较。 4.指针的类型转换 指针可以进行类型转换,但需要注意转换后的指针类型必须与指向的变量类型相同,否则可能会导致程序出错。 5.指针和数组 数组名本身就是一个指针,指向数组的第一个元素。可以使用指针来访问数组中的元素,也可以将指针作为函数参数来传递数组。 以下是一个例子,演示了指针的定义、初始化、运算和比较: ```c #include <stdio.h> int main() { int a = 10; int *p = &a; // 定义指向整型变量a的指针p printf("a的值为:%d\n", a); // 输出:a的值为:10 printf("p指向的变量的值为:%d\n", *p); // 输出:p指向的变量的值为:10 printf("p的值为:%p\n", p); // 输出:p的值为:0x7ffeeb5f8a2c printf("p+1的值为:%p\n", p+1); // 输出:p+1的值为:0x7ffeeb5f8a30 printf("p的地址为:%p\n", &p); // 输出:p的地址为:0x7ffeeb5f8a28 printf("p和&a的比较结果为:%d\n", p == &a); // 输出:p和&a的比较结果为:1 return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值