C++指针与引用简析

摘要

本文讲述C++中指针与引用的概念

什么是指针

指针的类型

指针所指向的类型

指针表达式

指针与函数

什么是引用

指针引用区别

指针和引用的相同点和不同点

**什么是指针**

指针就是一个存放地址的变量,

当指针指向某个变量,

这时这个指针里就存放了那个变量的地址 ,

同时可以利用指针直接取变量中的值用 ,只要在指针前加 * 就是
取其

真值了(也就是被指向的变量的值)

![指针示意](http://img.blog.csdn.net/20150605232124686)

**指针的类型**

int *p;  // 指针类型 int *
char *p;  // char *
int **p;  // int **
int (*p)[3];  // int *3
int *(*p)[4];  // int **4

**指针所指向的类型**

int *p; // int
char *p; //  char
int **p; //     int *
int (*p)[3]; //   int()[3]
int *(*p)[4]; //   int *()[4]  

总结:

1.指针的类型

从语法的角度看,指针声明语句里的指针名去掉,剩下部分就是指针的类型。是指针本身所具有的类型

2.指针所指向的类型

通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那块内存区当做什么来看待。

从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型

**指针表达式**

int a,b;
int array[10];
int *pa;
pa=&a; //  &a是一个指针表达式。
int **p=&pa;  //  &pa也是一个指针表达式。
*p=&b;  //  *p和&b都是指针表达式。
pa=array;
pa++;  //  这也是指针表达式。


char *array[20];
char **parr=array;//如果把arr看作指针的话,arr也是指针表达式
char *str;
str=*parr;//*parr是指针表达式
str=*(parr+1);//*(parr+1)是指针表达式
str=*(parr+2);//*(parr+2)是指针表达式  

指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存

指针与数组

int array[5]={0,1,2,3,4},value;
...
value=array[0];//   value=*array;
value=array[3];//    value=*(array+3);
value=array[4];//      value=*(array+4);  指针向后位移了+δ
char *str[3]={
"Hello,nice to meet you!",
"Hi,good night!",
"Hello world"
};
char s[80];
strcpy(s,str[0]);// or strcpy(s,*str);
strcpy(s,str[1]);//or  strcpy(s,*(str+1));
strcpy(s,str[2]);//or  写成strcpy(s,*(str+2));  

str是一个三单元数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指针数组名str当作一个指针的话,它指向数组的第0号单元,它的类型是char**,它指向的类型是char *。

str也是一个指针,类型是char,所指向的类型是char,它指向的地址是字符串”Hello,nice to meet you!”的第一个字符的地址,即’H’的地址。 str+1也是一个指针,它指向数组的第1号单元,它的类型是char**,它指向的类型是char *

**指针与函数**

int f1(char*,int);
int (*pf1)(char*,int);
pf1=f1;
....
int a=(*pf1)("abcdefg",7);   //   通过函数指针调用函数。  

什么是引用

引用是一个对象的别名,主要用于函数参数和返回值类型,符号X&表示X类型的引用

**指针引用区别**

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用不改变指向

**指针传递与引用传递**

1 指针传递

- 参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

-

2 引用传递

- 过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

**指针和引用的相同点和不同点**

  1. 相同点:

    • 都是地址的概念;

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

  1. 不同点:

    • 指针是一个实体,而引用仅是个别名;
    • 引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
    • 引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有 的, 前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)
    • 引用不能为空,指针可以为空;
    • “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;
    • 指针和引用的自增(++)运算意义不一样;
    • 引用是类型安全的,而指针不是 (引用比指针多了类型检查
时间: 2024-10-13 19:44:45

C++指针与引用简析的相关文章

面向对象多态简析

C#&C++多态问题简析 在学习C#面向对象时,对封装和继承基本上还是理解的,但是碰到多态,基本上就是记住了个父类引用指向子类对象,在很长时间内也是一直比较困惑.学习c++时,基本上算是有了一定了解.下面结合代码解释多态问题 首先是c#代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Duo

Android -- MediaPlayer内部实现简析

Android -- MediaPlayer内部实现简析 在之前的博客中,已经介绍了使用MediaPlayer时要注意的内容.现在,这里就通过一个MediaPlayer代码实例,来进一步分析MediaPlayer内部是如何运作.实现的:当然这里的分析只截止到底层调用播放器之前,因为播放器这块实在是没搞懂. 我们使用的例子来源于之前MediaPlayer Playback译文中的官方实例: String url = "http://........"; // your URL here

借助LANMT构架,简析ngnix的使用

LNMP流程图 nginx PHP Mysql Nginx Fastcgi_pass <-FastCGI-> fastcgi-(php-fpm)<->wrapper Php 解析器 (Php.ini) <->mysql fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->

JDK框架简析--java.lang包中的基础类库、基础数据类型

题记 JDK.Java Development Kit. 我们必须先认识到,JDK不过,不过一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含量来说.还是在一个层级上,它们都是须要被编译成字节码.在JRE中执行的,JDK编译后的结果就是jre/lib下的rt.jar,我们学习使用它的目的是加深对Java的理解,提高我们的Java编码水平. 本系列全部文章基于的JDK版本号都是1.7.16. 源代码下载地址:https://jdk7.jav

cgroup原理简析:进程调度

本篇来探究下cgroup对cpu的限制机制,前文提到过cgroup也是通过进程调度子系统来达到限制cpu的目的,因此需要了解下进程调度子系统. 因为是介绍cgroup的文章,因此只介绍进程调度中与cgroup密切关联的部分,详细完成的进程调度实现可参考进程调度的相关资料. 本文分为三个部分,首先介绍进程调度中的调度算法,在该基础上引入组调度,最后结合前面文章(cgroup原理简析:vfs文件系统)来说明上层通过echo pid >> tasks, echo n > cpu.shares等

简析 .NET Core 构成体系

简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代码开发.部署.运行过程 总结 前文介绍了.NET Core 在整个.NET 平台所处的地位,以及与.NET Framework的关系(原文链接),本文将详细介绍.NET Core 框架的构成和各模块主要功能,以及如何实现跨平台. 上图描述了 .NET Core的系统构成,最上层是应用层,是开发基于UI应用的

三层架构—简析

三层学习完了,第一次验收的时候,自己理解的也不是很到位,后来又重新敲了一遍登陆例子,查阅了一些资料 进行第二次验收才感觉清晰了许多.之前画时序图时我就想过时序图基本上也是很好的体现了三层,当时也和别人讨 论过这个问题.直到学完三层后,更加证明了这一点. 下面我将从理论和实践两个角度总结一下三层. 理论篇 为什么使用三层架构? 说白了,分层的目的是想将复杂问题简单化,也就是面向对象技术所崇尚的"高内聚,低耦合".当业务复杂到 一定程度,数据存储在独立的存储介质时适合用三层架构. 什么是三

英语本科毕业论文常见的八大问题简析

英语专业本科结业论文是对英语本科生四年学习结果的末了一次查验,能全面反应门生在四年学习历程中对所学的词汇.语法.写作知识的掌握程度,能查验门生利用所学知识阐发.办理题目标本领,综合表现某一文化.语言.商务等知识与写作.科研本领的联合运用程度.结业论文属于研究论文写作范畴,有特定的范例和方式,差别于平凡文学创作,不行以自出机杼.一样通常来讲,毕业论文包罗三部门:第一部门包罗标题.中文择要.英文择要.目次:第二部门是正文,包罗先容.文献回首.科研要领.论点睁开和论证部门,结论:第三部门包罗参考文献和

Unity3D研究之asset bundle 格式简析详解

Unity3D 的 asset bundle 的格式并没有公开.但为了做更好的差异更新,我们还是希望了解其打包格式.这样可以制作专门的差异比较合并工具,会比直接做二进制差异比较效果好的多.因为可以把 asset bundle 内的数据拆分为独立单元,只对变更的单元做差异比较即可. 网上能查到的资料并不是官方给出的,最为流行的是一个叫做 disunity 的开源工具.它是用 java 编写的,只有源代码,而没有给出格式说明(而后者比代码重要的多).通过阅读 disunity 的代码,我整理出如下记