广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++中指针的深入理解
  • 277
分享到

C/C++中指针的深入理解

2024-04-02 19:04:59 277人浏览 八月长安
摘要

目录计算机的内存模型指针与指针常量指针变量和指针常量指针变量和数组函数指针c++中的引用传值还是传引用C++中的new关键词总结计算机的内存模型 CPU是计算机的核心部件,要想让一

计算机的内存模型

CPU是计算机的核心部件,要想让一个CPU工作,就必须向它提供指令和数据,指令和数据在存储器中存放,也就是我们平时说的内存。

内存分为:物理内存和虚拟内存,物理内存对应着计算机中的内存条,虚拟内存是操作系统内存管理系统假想出来的,由于这些不是我们本文的重点,我们就不做区分。

在不考虑cpu缓存的情况下,计算机运行程序本质上是对内存中的数据的操作,存储器被划分为多个存储单元,存储单元从零开始顺序编号,CPU要从内存中读取数据,首先要指定存储单元的地址。

CPU从内存中读取数据的过程如图所示:

计算机为了方便管理内存,将内存的每个单元用一个数字编号

指针与指针常量

指针的本意就是内存地址,我们可以通俗的理解成内存编号,既然计算机通过编号来操作内存单元,这就造成了指针的高效率

指针变量:

  • 通俗理解为存储指针的变量,也就是存储内存地址(内存编号)的变量
  • 指针变量和int,float,char等类型一样同属变量类型,指针变量类型占四个字节(32位机器下),存储的是32位的内存地址
    星号:
  • 在C\C++中(*)被定义为取内容符号
  • 虽然所有指针变量占的内存大小和存储的内存地址大小都是一样的,但是由于存储的只是数据的内存首地址,所以指针变量存储的内存地址所指向的数据类型决定着如何解析这个首地址
  • 比如int型指针变量,我们需要从该指针变量存储的首地址开始向后一直搜索4个字节的内存空间
  • 所以当我们使用*p,必须知道p是一个什么类型的指针

指针变量和指针常量

指针变量首先是一个变量,由于指针变量存储了某个变量的内存首地址,我们通常认为"指针变量指向了该变量",同时指针变量时一个变量,它的值是可以变动的。

相反,指针常量可通俗地理解为存储固定的内存单元地址编号的量,它一旦存储了某个内存地址以后,不可再改存储其他的内存地址了

举个例子:


void f(const int *x,int *y)
{
	*x=2;//错误,由于x前面有个const修饰,所以不可以修改x所指向的内存单元的内容
	//正确写法
	*y=3;
}

指针变量和数组

先看一个例子:


	int a[5]={1,2,3,4,5};
	int *ptr=(int*)(&a+1);
	cout<<*(a+1)<<endl;
	cout<<*(ptr-1)<<endl;

输出结果为2和5,首先我们看一下&a+1的含义:

  • 我们知道C\C++中规定数组名表示这个数组的首地址,而这里出现了&a这样的符号,本来a就是指针常量,再次取地址难道不是非法操作?
  • 这时我们可以将这个&a看成是指向数组的指针,也称为行指针,&a的类型是int (*p)[5],一个步长即5个元素的长度,&a + 1代表往后移动一个步长

分析:

  • a表示的是第一个元素的首地址,那么a+1指向的就是下一个元素的内存首地址,所以*(a+1)=2
  • 而&a则表示整个数据的首地址,那么&a+1移动的内存数目就是整个数组所占字节数,假如原先数组中第一个元素的首地址是0,那么&a+1表示的就是20,而这个地址已经不属于数组了,接着通过(int*)(&a+1)将数组指针转换成整型指针,这样原先&a+1表示的数据范围20-39就缩小为20-23,正好是一个int型的大小,而ptr-1就是16了,表示的数据内存范围是16-19,这样*(ptr-1)正好是最后一个元素5了

上面的例子,只是通过简单的数据类型来说明内存分布,但是实际上一些复杂的数据类型,尤其是一些自定义的类或者结构体类型,内存分布还要充分考虑到字节对齐。

函数指针

函数指针是指向函数的指针变量,C\C++程序在编译时,每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址,有了指向函数的指针变量后,可用该指针变量调用函数,同时也可以做函数的参数

我们先看函数指针调用函数,如下:


int f(int x, int y) {
	return x + y;
}
//申明一个函数指针
typedef int (*pf)(int, int);
int main()
{
	int a = 1;
	int b = 2;
	//将函数f地址赋给函数指针pf
	pf = f;
	//利用函数指针调用函数
	int c = (*pf)(a, b);
	cout << c << endl;
}

需要注意的是,定义的函数指针类型时的函数签名(包括函数返回值和函数参数列表的类型,个数,顺序)要将赋值给该类型变量的函数签名保持一致,不然可能会发生很多无法预料的情况,还有C\C++规定函数名就表示函数入口地址,所以,函数名赋值时函数名前面加不加取地址符&都一样,但是在C++中取类的方法函数的地址时,这个&符号不能省略。

函数指针还有另外一个用处,就是作为一个函数的参数,在windows编程中作为回调函数很常见:


typedef int (*PF)(int, int);
int f1(int x, int y)
{
	return x + y;
}
int f2(PF pf, int t)
{
	return (*pf)(3, t);
}
int main()
{
	//将函数f1作为参数传递给函数f2
	int c = f2(f1, 4);
	cout << c << endl;
	return 0;
}

C++中的引用

所谓引用,使用另外一个变量名来代表某一块内存,这就相当于同一个人有不同的名字,但是不管哪个名字,指的都是同一个人。


int a=1;
//通过&符号,将b定义为a的引用
int &b=a;
//b和a完全一样,等价于int c=a
int c=b;

注意,C++规定,定义一个引用的时候,必须马上初始化

传值还是传引用

如果变量类型是基元数据类型,比如int,float,bool,char等小数据类型被称为基元数据类型,那么赋值时传的是值,这时候b的值是a的拷贝,那么更改b不会影响到a,但是,如果变量数据类型是复杂数据类型,比如数组,类对象,那么赋值时传的就是引用,这个时候,a和b指向的都是同一个内存区域,那么无论更改a或者b都会相互影响。

最后,在利用C++中拷贝构造函数复制对象时需要注意,基元数据类型可以直接复制,但是对于引用类型数据,我们需要实现引用类型的真正复制

C++中的new关键词

在c++中通过new关键词定义一个对象,不能直接得到对象的实例,我们需要用一个指针去接收这个new出来的对象,我们引用这个对象必须使用指针引用运算符->


#include <iOStream>
using namespace std;
class Person
{
public:
	Person()
	{

	}
	Person(int a, int b)
	{
		this->m_a = a;
		this->m_b = b;
	}
	int m_a;
	int m_b;
};
int main()
{
	//在C++中可以用以下形式来实例化一个对象,per1和per2为实例化的person类对象
	Person per1;
	int i = 1;
	int j = 2;
	Person per2(i, j);
}

在C++中,this关键词是一个指针,而不像在java中是一个类实例,在C++中*this才等价于java


class Person
{
public:
	Person(int number)
	{
		//C++中需要使用指针引用符号
		this->m_number = number;
	}
	//返回对象本身,,需要使用引用,因为返回值时会创建一个新的对象,使用引用的方式不会创建新的对象
	Person& getSelf()
	{
		return *this;
	}
	int m_number;
};

总结

到此这篇关于C/C++中指针的文章就介绍到这了,更多相关C/C++指针理解内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C/C++中指针的深入理解

本文链接: https://www.lsjlt.com/news/130897.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C/C++中指针的深入理解
    目录计算机的内存模型指针与指针常量指针变量和指针常量指针变量和数组函数指针C++中的引用传值还是传引用C++中的new关键词总结计算机的内存模型 CPU是计算机的核心部件,要想让一...
    99+
    2022-11-12
  • 深入理解c++指针的指针和指针的引用
    在C++中,指针是一种数据类型,可以存储变量的内存地址。指针的指针和指针的引用是两种特殊的指针类型。指针的指针是指一个指针变量的值是另一个指针的地址。也就是说,指针的指针存储的是一个指针变量的地址。可以通过多次间接引用来获取最终指向的变...
    99+
    2023-08-09
    c++
  • 深入理解C#指针之美
    目录一、简洁优美的代码二、C# 指针基础三、几种常用用法1、使用Dispose模式管理非托管内存2、使用 stackalloc 在栈中分配内存3、模拟C中的union(联合...
    99+
    2022-11-12
  • 深入理解C语言的指针
    目录起源进程内存布局栈设置分配方式特点堆分配方式特点堆与栈区别扩展总结起源 之前在知乎上看了一句话,指针是C的精髓,也是初学者的一个坎。换句话说,内存管理是C的精髓,C/C++可以直...
    99+
    2022-11-12
  • C语言由浅入深理解指针
    目录1. 相关概念2. 指针的定义方法3. 指针的分类4. 指针和变量的关系5. 指针与数组的关系6. 指针的运算1. 相关概念 操作系统给每个存储单元分配了一个编号,从ox00 0...
    99+
    2022-11-13
  • 怎样深入理解C语言的指针
    本篇文章给大家分享的是有关怎样深入理解C语言的指针,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。起源之前在知乎上看了一句话,指针是C的精髓,也是初学者的一个坎。换句话说,内存管...
    99+
    2023-06-26
  • 深入了解C语言指针
    目录指针是什么?指针和指针类型指针运算总结指针是什么? 总结:指针就是个变量,变量里面是地址,指针就是地址。(存放在指针的值都被当成地址处理)。 注:指针的大小在32位平台是4个字节...
    99+
    2022-11-12
  • C/C++函数指针深入探究
    目录函数指针语法函数地址声明使用函数指针调用函数深入理解函数指针使用typedef 简化函数指针 为什么要使用函数指针? 调用的灵活性和通用性。 试想一下,我们在设计初期并不知道我们...
    99+
    2022-11-13
  • 深入了解C语言中的const和指针
    目录前言指针的赋值问题ANSI C 有关简单赋值的标准问题解决const修饰const修饰变量const修饰指针前言 文章内容由阅读《C专家编程》整理而来。希望可以帮助大家解决在指针...
    99+
    2022-11-13
  • C++深入分析讲解智能指针
    目录1.简介2.unique_ptr指针(独占指针)3.shared_ptr指针(共享所有权)4.weak_ptr(辅助作用)5.自实现初级版智能指针6.总结1.简介 程序运行时存在...
    99+
    2022-11-13
  • 深入了解C++智能指针的使用
    目录一、C++11智能指针概述二、C++98中的智能指针三、C++11中的智能指针1.unique_ptr2.shared_ptr3.weak_ptr一、C++11智能指针概述 在C...
    99+
    2022-11-13
  • 深入了解C++中常用的三个智能指针
    目录什么是智能指针C++中的几种智能指针unique_ptrshared_ptrweak_ptr总结什么是智能指针 在C++中,内存的分配和释放都是由开发者手动实现的。这种方式虽然很...
    99+
    2023-05-18
    C++智能指针 内存管理 C++智能指针使用 C++ 智能指针
  • 深入浅出理解C语言指针的综合应用
    目录指针是什么?指针变量  使用指针变量的例子通过指针引用数组&数组名vs数组名野指针野指针成因1.指针未初始化2.指针越界访问如何避免野指针指针运算指针是什么? ...
    99+
    2022-11-13
  • C语言深入浅出讲解指针的使用
    目录一、利用指针倒序字符串二、题目实例三、总结一、利用指针倒序字符串 void _reversal(char* left, char* right) { while (lef...
    99+
    2022-11-13
  • C++深入浅出讲解隐藏this指针的用法
    目录1.this指针的引出2.this指针的特性3.练习一下本篇文章我们将一起讨论在有趣的知识点--隐藏的this指针。本篇我们要使用到之前我们所学习到的C++类与对象,如果有各位小...
    99+
    2022-11-13
  • 深入理解C语言中使用频率较高的指针与数组
    目录定义指针与二维数组指针数组与数组指针数组指针的应用操作总结定义 指针:C语言中某种数据类型的数据存储的内存地址,例如:指向各种整型的指针或者指向某个结构体的指针。 数组:若干个相...
    99+
    2022-11-13
  • C语言深入讲解指针与结构体的使用
    目录1 啥是指针1.1指针与指针变量1.2总结2 指针和指针类型2.1指针+-整数3 野指针3.1 野指针的成因1指针未初始化2指针越界访问3指针指向的空间释放3.2 如何避免野指针...
    99+
    2022-11-13
  • C语言深入分析数组指针和指针数组的应用
    目录一、数组类型二、定义数据类型三、数组指针四、指针数组五、小结一、数组类型 C语言中的数组有自己特定的类型数组的类型由元素类型和数组大小共同决定 例:int array[5] 的类...
    99+
    2022-11-13
  • C++深入讲解引用的特点及与指针的区别
    目录一.引入二.C++中较为麻烦的运算符三.引用的定义四.引用的特点五.对比指针与引用六.引用与指针的区别1.语法层面的区别2.汇编层面的区别七.引用的其他使用常引用数组引用指针引用...
    99+
    2022-11-13
  • C语言中二级指针解析(指向指针的指针)
    目录二级指针(指向指针的指针)二级指针的定义与理解二级指针定义格式二级指针赋值实例二级指针(指向指针的指针) 指针可以指向一份普通类型的数据,例如 int、double、char 等...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作