C语言指针2大问题:指针类型有什么用?指针如何运算?

这篇具有很好参考价值的文章主要介绍了C语言指针2大问题:指针类型有什么用?指针如何运算?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如题,本篇博客主要解决2个疑点:指针类型的用处,指针如何运算。

C语言指针2大问题:指针类型有什么用?指针如何运算?

1.指针类型

C语言中的指针类型,在X86环境下大小是4个字节,在X64环境下大小是8个字节。既然指针的大小和指针类型无关,那么指针类型究竟有什么用呢?

事实上,指针类型决定看待内存的视角,具体是以下2点:

  1. 指针“走一步”能走多远。
  2. 指针解引用时,访问的权限。

1.1 决定步长

先说第一点。假设给一个int*类型的指针和一个char*类型的指针+1,分别跳过几个字节呢?

#include <stdio.h>

int main()
{
	int a = 100;
	int* pa = &a;
	char c = 'f';
	char* pc = &c;

	printf("    pa = %p\n", pa);
	printf("pa + 1 = %p\n", pa + 1);
	printf("    pc = %p\n", pc);
	printf("pc + 1 = %p\n", pc + 1);

	return 0;
}

输出结果:
C语言指针2大问题:指针类型有什么用?指针如何运算?
有意思的是,int*类型的指针+1会跳过4个字节,而char*类型的指针+1会跳过1个字节。

这是为什么呢?在整型指针眼里,内存中的数据都是int类型的,如果+1,自然跳过一个int,也就是跳过了4个字节。同理,在字符指针眼里,内存中的数据都是char类型的,如果+1,自然跳过一个char,也就是跳过了1个字节。

那+2,+3,-1呢?如果是整型指针,+2就应该跳过2个整型,也就是向后跳8个字节。而-1就应该向前跳过1个整型,也就是向前跳4个字节。其实,这就是指针的运算之一:指针±整数。

综上所述:指针的类型,决定了指针±整数时,向前/后走的步长。具体来说,对于一个type*类型的指针,±n后,会向后/前跳过n*sizeof(type)个字节。

1.2 决定访问权限

如果对一个int*类型的指针解引用,在整型指针眼里,内存中的数据都是整型,解引用后,会向后看4个字节,并且认为这4个字节中,存储的数据是整型。如果对一个char*类型的指针解引用,在字符指针眼里,内存中的数据都是字符,解引用后,会向后看1个字节,并且认为这1个字节中,存储的数据是字符。

如何验证这一点呢?可以这样做:假设内存中存储了一个16进制数字:

int a = 0x11223344;

如果我把它的地址给一个int*类型的指针,再解引用会发生啥?

int* pa = &a;
*pa = 0;

如果大家对指针有一定的了解,应该知道,pa里存的是a的地址,对pa解引用,就能访问a,并且把a给改了,a的值就变成了0。而a是4个字节的数据,这一改,其实把这4个字节都改成了0,这就证明了int*类型的指针解引用会访问4个字节。

那如果是char*类型的指针呢?

char* pc = &a;
*pc = 0;

我们来观察一下内存。这是修改前:
C语言指针2大问题:指针类型有什么用?指针如何运算?
由于我的环境是小端字节序,在内存中是倒着存储的。此时如果执行*pc = 0;,会发生啥?
C语言指针2大问题:指针类型有什么用?指针如何运算?
第一个字节的数据被改成了0!也就是说,对一个char*类型的指针解引用,只会访问一个字节的数据。

综上所述:指针类型决定了访问的权限,即解引用后能访问几个字节。一个type*类型的指针,解引用后能访问sizeof(type)个字节。

2.指针运算

指针有4中常见运算,分别是:

  1. 解引用。
  2. ±整数。
  3. 指针-指针。
  4. 指针之间的大小比较。

下面分别详细讲解。

2.1 指针的解引用

对一个指针解引用,会先在内存中找到指针变量中存放的地址处,再根据指针变量的类型决定访问的权限。

比如,一个很基础的代码:

int a = 10;
int* pa = &a;
*pa = 20;

int* pa = &a;这句代码中,会把a的地址存放到pa中。而*pa = 20;这句代码会如何执行呢?

  1. 首先,在pa中取出前面存放的a的地址。
  2. 在内存中,找到该地址。
  3. 根据pa的类型是int*,决定了看待内存的视角:一次访问4个字节的空间,且这4个字节的空间内存储的类型是int。
  4. 以存储的地址为首地址,向后访问4个字节,认为这4个字节存储的数据是int数据,并且把这个数据改成20。

2.2 指针±整数

指针±整数,这个整数是几,就会根据指针的类型,向后/前跳过几个该类型的元素,其中“加”就向后跳,“减”就向前跳。

一个很经典的例子,就是使用指针访问数组。

int arr[] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr;
for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i)
{
	printf("%d ", *(p+i));
}

这里的p+i,就会从p指向的位置开始,向后跳i个int类型的数据,其实就相当于找到了数组下边为i的元素,此时解引用就能拿到这个元素。

咦,有没有发现,*(p+i)似乎作用就相当于arr[i]?而我们前面写了int* p = arr;是不是可以理解为,p就等价于arr,也就是说,下面这4个玩意是等价的:

*(p+i) <—> *(arr+i) <—> arr[i] <—> p[i]

所以,用下标访问数组,如arr[i]的形式,其实本质上就是指针±整数指针的解引用的结合!

2.3 指针-指针

指针-指针,得到的是指针之间的元素个数。比如:

int arr[10];
int n = &arr[9] - &arr[0];

上述代码中,n就是9,因为arr[9]和arr[0]都是int类型的数据,取出地址后,会得到2个int*类型的指针。它们的差,就是arr[9]和arr[0]相差了几个int类型的数据,显然是9个,所以答案是9。注意,如果写成&arr[0] - &arr[9],得到的就是-9。

其实,根据前面的讲解,a[i]就等价于*(a+i)。那么,下面的等式成立(这是一个不太严谨的理解):

&arr[9]-&arr[0] = &*(arr+9) - &*(arr+0) = (arr+9) - (arr+0) = 9

是不是很有意思?

2.4 指针之间的大小比较

这个就很简单了,单纯是比较指针变量存储的地址之间的大小。

比如,随着数组下标的增长,地址是由低到高变化的,所以就有:&arr[0] < &arr[9]。

总结

  1. 指针的类型决定了看待内存的视角。具体决定了指针±整数时的步长,以及解引用时访问的权限。
  2. 指针主要有4种运算,分别是:解引用,±整数,指针-指针以及指针的关系运算。

感谢大家的阅读!文章来源地址https://www.toymoban.com/news/detail-425391.html

到了这里,关于C语言指针2大问题:指针类型有什么用?指针如何运算?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言趣味教程】(5) 常量:字面常量 | 类型常量 | const 关键字 | const 的声明 | 程序中的只读概念 | const 保护机制 | 如何巧妙区分 “指针常量“ 和 “常量指针“

        🔗 《C语言趣味教程》👈 猛戳订阅!!! ✨ 专栏介绍 / 总目录: 【C语言趣味教程】(0) 导航篇 ​ —— 热门专栏《维生素C语言》的重制版 —— 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人

    2024年02月15日
    浏览(44)
  • 【C语言初阶】带你轻松掌握指针基础知识完结篇——野指针,指针运算,指针和数组,二级指针

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,这里是君兮_,今天继续给大家更新0基础入门C语言的内容,我们这次主要更新的依然是初阶指针的基础知识 废话不多说咱们直接开始吧!! 概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有

    2024年02月16日
    浏览(45)
  • 【C语言初阶】指针的运算or数组与指针的关系你了解吗?

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,前面给大大家介绍了指针的基础知识。那么这一章就来给大家介绍下一部分内容!    ⛳️ 指针的运算 以及 数组与指

    2024年02月16日
    浏览(35)
  • 【C语言】初阶指针(指针及其类型以及野指针)

    简单不先于复杂,而是在复杂之后。 目录 1. 指针是什么? 2. 指针和指针类型  2.1  指针+-整数 2.2 指针的解引用  3. 野指针  3.1 野指针成因  3.2 如何规避野指针  指针理解的两个要点: 1. 指针是内存中最小单元的编号,也就是地址。 2. 平时口语中说的指针,通常指的是指

    2023年04月16日
    浏览(47)
  • 【进阶C语言】进阶指针--学会所有指针类型

     本节内容大致目录: 1.字符指针 2.指针数组(数组) 3.数组指针 (指针)--比较重要 4.函数指针--比较重要 5.函数指针数组--用的较少 6.指向函数指针数组的指针--只需要了解就可以 需要掌握每一种类型的符号和用处。 前言:字符指针是一种指针,是众多指针类型中的一种。

    2024年02月07日
    浏览(42)
  • C语言——函数指针类型转换

    昨天为了避免跨层调用API搞了个回调函数,用了函数指针,因为参数类型的问题总是编译报错,今天就看了两篇博文学习学习,顺便做做笔记。 其实正常来讲只要把函数指针的参数个数、类型和返回值这些函数指针的标签或者说是属性写对了的话就不会有社么问题,但我也不

    2024年01月16日
    浏览(35)
  • C语言:指针类型的意义

    1.指针的类型决定了解引用时访问几个字节 2.指针的类型决定了指针+1、-1跳过几个字节 一、指针的类型决定指针解引用时访问几个字节 例如 int 型指针解引用时访问4个字节         char 型指针解引用时访问1个字节   详解代码如下: int b = 0x11223344(十六进制,小端存储,实

    2024年02月11日
    浏览(41)
  • C# 使用SIMD向量类型加速浮点数组求和运算(4):用引用代替指针, 摆脱unsafe关键字,兼谈Unsafe类的使用

    作者: zyl910 目录 一、引言 二、办法说明 2.1 历史 2.2 局部引用变量与引用所指的值(类似指针的 地址运算符 、间接运算符 * ) 2.3 重新分配局部引用变量(类似指针直接赋值) 2.4 引用地址调整(类似指针加减法) 2.5 引用地址比较(类似指针比较) 2.6 重新解释(类似C++的

    2024年02月15日
    浏览(42)
  • 【C语言】——认识指针变量和地址,以及指针变量类型的意义

    🎥 岁月失语唯石能言的个人主页         🔥 个人栏专: 秒懂C语言 ⭐ 若在许我少年时,一两黄金一两风      目录 前言 一、指针变量和地址 1.1 取地址操作符() 1.2 指针变量和解引用操作符(*) 1.2.1 指针变量 1.2.2 如何拆解指针类型 1.2.3 解引用操作符 1.3 指针变量

    2024年02月04日
    浏览(55)
  • Go语言之流指针类型,new函数

    计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。 我们将内存中字节的

    2024年02月16日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包