对指针和引用的理解(c++)

1.指针

typedef说明一种新类型名,来代替已有类型名。

a.案例:typedef char String_t和#define String_d char 这两句在使用上的区别?

1)前者声明一个类型的别名,在编译时处理,有类型检查。后者是一个简单的替换,在预编译时处理,无类型检查。

2)String_t a,b;中a和b都是char类型的。但是String_d a,b;中a是char类型的,b是char类型的。

b.对 typedef string *pstring;

const pstring cstr;的理解。

cstr是一种指针,指向string类型的const对象。但这是错误的。错误的原因在于将typede当作宏替换似的文本扩展了。声明 const pstring时,const修饰的是pstring的类型。

这是一个指针。所以该声明应该是把cstr定义为指向string类型对象的const指针。等价于:string * const cstr;

c.void指针。void 指针表明该指针与一地址值相关,但是不清楚存储在该地址值上的对象类型。void*指针只支持有限的操作:

1)与另外一个指针进行比较

2)向函数传递void指针或从函数返回void指针。

3)给另外一个void指针赋值。不允许使用void指针操作他所指向的对象。当函数返回void*类型时,表示返回一个特殊指针类型。而不是返回类型为void那样表示无返回值。

d.用typedef简化函数指针的定义

typedef bool (*cmpFcn)(const string &,const string &);

该定义表示cmpFcn是一种指向函数的指针类型的名字。该指针类型为指向返回bool类型并带两个const string 引用形参的函数的指针,在要使用这种函数指针类型时,

只需直接使用cmpFcn即可,不必每次都把整个类型声明全部写出来。

在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。

bool lengthCompare(const string &,const string &);

直接引用函数名等效于在该函数名上应用取地址操作符:

cmpFcn pf1=lengthCompare;

cmpFcn pf2=&lengthCompare;

函数指针的使用

指向函数的指针可以用于调用他所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数。

例如: typedef bool(*cmpFcn)(const string &,const string &);

bool lengthCompare(const string &,const string &);

则:cmpFcn pf=lengthCompare;

lengthCompare(“hi”,”bye”); //直接调用lengthCompare函数

pf(“hi”,”bye”); // 利用函数指针调用lengthCompare函数,未使用*

pf)(“hi”,”bye”); // 利用函数指针调用lengthCompare函数,使用

函数的形参为指针和返回指向函数的指针

允许将形参定义为函数类型,但是函数的返回类型则必须是指向函数的指针,而不能是函数。具有函数类型的形参所对应的实参将被自动转换为指向相应函数类型的指针。

但是,当返回的是函数类型时,同样的转换操作将无法实现。

func f2(int); //错误,func无法自动转换。

func* f3(int); //正确,f3返回一个函数指针

2.引用

引用就是对象的另外一个名字。c++中规定一旦定义了引用,就必须把它跟一个变量绑定起来,并且不能修改这个绑定。

不能定义引用类型的引用,但是可以定义其他类型的引用。

使用引用和指针都可以间接的访问另外一个值,但是他们之间有几个重要的区别。

1)引用不能为空,当引用被创建时,他必须被初始化,而指针可以为空值,可以在任何时候被初始化。

2)一旦一个引用被初始化为指向一个对象,他就不能改变为对另外一个对象的引用,指针则可以在任何时候指向另外一个对象。

3)不可能有NULL引用。必须确保引用和一块合法的存储单元关联。

4)sizeof(引用)得到的是所指向变量(对象)的大小,而sizeof(指针)得到指针本身的大小。

5)给引用赋值修改的是该引用所关联的对象的值,而并不是使引用于另外一个对象的关联。

6)引用使用时不需要解引用,而指针需要解引用,引用和指针的自增(++)操作符运算意义不同。

7)如果返回动态分配的对象或内存,必须使用指针,引用可能引起内存泄漏。

8)当使用&运算符取一个引用的地址时,其值为所引用变量的地址。而对指针使用&运算,取得是指针变量的地址。

可见引用本质只是一个对象的别名。对引用别名的操作即是对本身变量的操作。

const引用

const引用是指向const对象的引用。当引用的对象是const对象时,引用也必须是const。

const int ival=1024;

const int &refVal=ival; //正确

int& ref2=ival; //错误

如果既要既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应该使用常引用。常引用主要用于定义一个普通变量只读属性的别名。

作为函数的传入形参,避免实参在调用函数中被意外改变。

引用做类的数据成员

引用类型数据成员的初始化有一下几个特点:

1)不能直接在构造函数中初始化,必须用到初始化列表。

2)凡是用引用类型的数据成员的类,必须定义构造函数。

案例:

class ConstRef{

public:

ConstRef(int ii):i(ii),ci(i),ri(ii){} //ci与ri必须在成员初始化列表中初始化,因此必须自定义构造函数,书写成员初始化列表

private:

int i;

const int ci;

int &ri;

Original: https://www.cnblogs.com/mydomain/p/10149718.html
Author: 浪里飞
Title: 对指针和引用的理解(c++)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536319/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • EclipseC++学习笔记-8 兼容vim

    1、搜索vim2、点击install 本博客是个人工作中记录,遇到问题可以互相探讨,没有遇到的问题可能没有时间去特意研究,勿扰。另外建了几个QQ技术群:2、全栈技术群:616945…

    C++ 2023年5月29日
    044
  • Visual C++ 运行库合集包完整版 v20201209

    Microsoft Visual C++ Redistributable(系统运行库,简称MSVC,VB/VC)是Windows操作系统应用程序的基础类型库组件。 此版Visual…

    C++ 2023年5月29日
    067
  • C++11 lambda表达式

    C++11引入了lambda表达式,使得程序员可以定义匿名函数,该函数是一次性执行的,既方便了编程,又能防止别人的访问。 Lambda表达式的语法通过下图来介绍: 这里假设我们定义…

    C++ 2023年5月29日
    051
  • windows下使用vscode编写运行以及调试C/C++

    c++本地运行和debughttps://www.cnblogs.com/TAMING/p/8560253.html 运行C++/C代码 在终端运行 文件读入https://blo…

    C++ 2023年5月29日
    041
  • 逆向初级-C++(三)

    1、什么是封装:将函数定义到结构体内部,就是封装。2、什么是类:带有函数的结构体,称为类。3、什么是成员函数:结构体里面的函数,称为成员函数。 #include #include …

    C++ 2023年5月29日
    055
  • C++ 回调函数详解

    1、什么是回调函数回调函数本质上也是普通函数,只是调用机制有所区别——首先通过传参的形式将该函数的地址传递给其他函数,然后在其他函数中通过函数指针调用该函数。在其他函数中通过函数指…

    C++ 2023年5月29日
    069
  • C++ *和&

    概述 在c++中,当申明变量int *p 的时,表示p是一个储存地址的变量;比如int _p=0,表示p指向地址为00000000的地址单元。当申明指针p之后,再用_p表示p指向的…

    C++ 2023年5月29日
    051
  • 【C++自绘控件】如何用GDI+来显示图片

    在我们制作一个应用软件的时候往往需要在窗口或控件中添加背景图。而图片不仅有BMP格式的,还有JPEG、PNG、TIFF、GIF等其它的格式。那么如何用jpg格式的图片来当背景呢? …

    C++ 2023年5月29日
    057
  • C++ d-bus 使用实例

    因为以后工作用的到D-bus,这两天抽空看了下c++下得d-bus的使用方法。因为网上对c++下得d-bus使用说明几乎没有,所以,在这里记录下以供同仁使用。同时感谢shengpe…

    C++ 2023年5月29日
    055
  • Floyd算法(二)之 C++详解

    和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授…

    C++ 2023年5月29日
    078
  • !! vc C++ VS2017检查内存泄漏具体到某一行代码

    VLD工具可以用来检查VS C++程序的内存泄露。 VLD官网:https://kinddragon.github.io/vld/ 官网不方便下载的,可以用我的链接:https:/…

    C++ 2023年5月29日
    043
  • C++引用 学习心得

    参数的传递本质上是一次赋值的过程,赋值就是对内存进行拷贝。所谓内存拷贝,是指将一块内存上的数据复制到另一块内存上。 对于像 char、bool、int、float 等基本类型的数据…

    C++ 2023年5月29日
    066
  • C++矩阵运算库推荐

    最近在几个地方都看到有人问C++下用什么矩阵运算库比较好,顺便做了个调查,做一些相关的推荐吧。主要针对稠密矩阵,有时间会再写一个稀疏矩阵的推荐。 Armadillo:C++下的Ma…

    C++ 2023年5月29日
    062
  • [转] C++ STL中map.erase(it++)用法原理解析

    总结一下map::erase的正确用法。首先看一下在循环中使用vector::erase时我习惯的用法: 这一种用法是没有问题的。 如上所示,C++98中map::erase并没有…

    C++ 2023年5月29日
    058
  • 生成1~n之间随机整数_c++

    rand() % (high – low + 1) + low; Original: https://www.cnblogs.com/douzujun/p/16457919.htm…

    C++ 2023年5月29日
    034
  • C++ STL std::copy 详解

    std::copy(start, end, std::back_inserter(container)); 这里,start和end是输入序列(假设有N个元素)的迭代器(itera…

    C++ 2023年5月29日
    055
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球