C++中的指针、数组指针与指针数组、函数指针与指针函数


本文从刚開始学习的人的角度,深入浅出地具体解释什么是指针、怎样使用指针、怎样定义指针、怎样定义数组指针和函数指针。并给出相应的实例演示。接着,差别了数组指针与指针数组、函数指针与指针函数;最后。对最常混淆的引用传递、值传递和指针传递做了区处。

C++中一个重要的特性就是指针,指针不仅具有获得地址的能力,还具有操作地址的能力。指针能够用于数组、或作为函数的參数,用来訪问内存和对内存的操作,指针的使用使得C++非常高效。可是指针也非常危急。使用不当会带来比較严重的问题。

1、指针

程序中全部的变量和常量都存在一个内存地址中,当然,函数也有相应的内存地址,内存地址的不同会导致程序运行时有所不同。

指针就是用来控制和存储内存地址的变量。它指向单个对象的地址。除了void之外,指针的数据类型与所指向地址的变量数据类型保持一致。

2、怎样定义指针、数组指针、函数指针

常见的指针定义有3种:变量指针、数组指针和函数指针的定义。

(1)、变量指针的定义

int* p=0;	//定义指针p。并初始化指针为0。即指向的地址为0000 0000

int a=0; //定义初始化常量a
int* p; //定义指针p
p=&a; //指针p指向a的地址,即指针获取地址

(2)、数组指针的定义

int a[]={0,1,2,3,4,5,6,7,8,9};	//定义数组
int* p=a; //定义并赋值数组指针,即获得数组的首地址

(3)、函数指针的定义

int f();	//定义函数
int (*p)(); //定义函数指针
p=f; //赋值函数指针。即获得函数代码的首地址

差别变量指针、数组指针和函数指针的定义的演示样例代码例如以下。

#include<iostream>
using namespace std; int f() //定义一个函数
{
cout<<"測试函数指针的使用"<<endl<<endl;
return 0;
} void main()
{
cout<<"==========变量指针的使用=========="<<endl;
int a=5;
int* p=0; //初始化指针为0
int* q; //定义指针
q=&a; //赋值指针
cout<<"a = "<<a<<endl; //变量a的值
cout<<"a = "<<*q<<endl; //变量a的值
cout<<"p = "<<p<<endl; //指针p的地址为0000 0000
cout<<"&a = "<<&a<<endl; //获取a的地址
cout<<"&a = "<<q<<endl; //获取a的地址 cout<<"==========数组指针的使用=========="<<endl;
int b[]={0,1,2,3,4,5,6,7,8,9};
int* pb=b; //直接指向第一个元素的地址
cout<<pb<<endl //第1个元素的地址,即数组的首地址
<<b<<endl //第1个元素的地址,即数组的首地址
<<*pb<<endl //第1个元素的值
<<(*pb+2)<<endl; //第3个元素的值 cout<<"==========函数指针的使用=========="<<endl;
int f(); //定义函数
int (*pf)(); //定义函数指针
pf=f; //赋值函数指针,即将函数的首地址赋值给指针pf
(*pf)(); //通过函数指针调用函数
}

结果例如以下图:

3、数组指针与指针数组

数组指针是一个指针变量,它指向一个数组。即指向一个数组的指针就是数组指针。而指针数组是一个仅仅包括指针元素的数组,它的元素能够指向同样类型的不同对象。

4、函数指针与指针函数

函数指针就是指向函数的存储空间地址的指针,能够对函数指针进行赋值而且通过函数指针来调用函数,它的本质是一个指针。而指针函数仅仅是说明它是一个返回值为指针的函数。其本质是一个函数。

5、引用传递、值传递和指针传递

C++语言中。函数的參数和返回值的传递方式有3种:即值传递、引用传递和指针传递。

(1)、值传递

形參是实參的拷贝,改变形參的值并不会影响外部实參的值。

从被调用函数的角度来说,值传递是单向的(实參->形參)。參数的值仅仅能传入,不能传出。当函数内部须要改动參数,而且不希望这个改变影响调用者时。採用值传递。

(2)、指针传递

形參为指向实參地址的指针,当对形參的指向操作时。就相当于对实參本身进行的操作。

(3)、引用传递

形參相当于是实參的“别名”,对形參的操作事实上就是对实參的操作。在引用传递过程中,被调函数的形式參数尽管也作为局部变量在栈中开辟了内存空间,可是这时存放的是由主调函数放进来的实參变量的地址。被调函数对形參的不论什么操作都被处理成间接寻址。即通过栈中存放的地址訪问主调函数中的实參变量。

正由于如此,被调函数对形參做的不论什么操作都影响了主调函数中的实參变量。

最后,总结一下指针和引用的同样点和不同点:

同样点:

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

不同点:

指针是一个实体,而引用仅是个别名;

引用仅仅能在定义时被初始化一次,之后不可变。指针可变。引用“从一而终”,指针能够“见异思迁”;

引用没有const,指针有const,const的指针不可变;(详细指没有int& const a这样的形式,而const int& a是有的,前者指引用本身即别名不能够改变,这是当然的,所以不须要这样的形式。后者指引用所指的值不能够改变)

引用不能为空。指针能够为空;

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

指针和引用的自增(++)运算意义不一样;

引用是类型安全的,而指针不是(引用比指针多了类型检查)。

C++中的指针、数组指针与指针数组、函数指针与指针函数的更多相关文章

  1. c语言中如何通过二级指针来操作二维数组

    通过二级指针去访问二维数组需要先给二级指针分配等同于二维数组行数的一维数组指针,然后把二维数组的每行首地址赋值给对应位置的一维指针上.之后就可以通过二维指针直接访问了. 参考代码如下,可以看具体注释辅 ...

  2. 《征服 C 指针》摘录3:数组 与 指针

    一.数组 和 指针 的微妙关系 数组 是指将固定个数.相同类型的变量排列起来的对象. 正如之前说明的那样,给指针加 N,指针前进“当前指针指向的变量类型的长度 X N”. 因此,给指向数组的某个元素的 ...

  3. &lt;深入理解C指针&gt;学习笔记和总结 第四章 指针和数组

    数组是一个什么玩意: 数组和指针我的理解,有同样之处也有不同之处.因有同样之处,因此一些资料上说,数组和指针本质是同样的.因有不同之处,因此也有一些资料上说,数组和指针是不一样的. 同样之处: 数组名 ...

  4. C语言基础知识点整理(函数/变量/常量/指针/数组/结构体)

    函数 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...

  5. [C++基础]那些容易被混淆的概念:函数/数组指针-指针函数/数组,类/函数模板-模板类/函数

    函数指针-指针函数 函数指针的重点是指针.表示的是一个指针,它指向的是一个函数.eg: int (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.eg: int* fun() ...

  6. 《C专家编程》数组和指针并不同--多维数组

    <C专家编程>数组和指针并不同 标签(空格分隔): 程序设计论著笔记 1. 背景理解 1.1 区分定义与声明 p83 声明相当于普通声明:它所说明的并不是自身,而是描写叙述其它地方创建的对 ...

  7. go语言笔记——切片底层本质是共享数组内存!!!绝对不要用指针指向 slice切片本身已经是一个引用类型就是指针

    切片 切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型) ...

  8. c++指针数组与二维数组的最大区别

    下面随笔是关于指针数组说明及与二维数组的最大区别. 指针数组 数组的元素是指针型 例 利用指针数组存放矩阵 1 #include 2 using namespace std; 3 int main() ...

  9. c++函数内部可以返回函数内部定义的指针 但是不能返回函数内部定义的数组

    1.返回数组 // demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> char *m ...

  10. C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数

    返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用  和 返回一个含 ...

随机推荐

  1. 关于Android真机调測Profiler

    u3d中的Profile也是能够直接在链接安卓设备执行游戏下查看的,导出真机链接U3D的Profile看数据,这样能更好的測试详细原因. 大概看了下官方的做法.看了几张帖子顺带把做法记录下来. 參考: ...

  2. Java实现斐波那契数列Fibonacci

    import java.util.Scanner; public class Fibonacci { public static void main(String[] args) { // TODO ...

  3. 转一篇关于vuex简单理解的文章

    学习vuex半天摸不着头脑无意间发现了这篇文章 对vuex做了一个简单的阐述比较有助于我的理解 现在分享出来希望能给一些朋友一点帮助  这个是原文地址 http://www.ituring.com.c ...

  4. 51nod-1310: Chandrima and XOR

    [传送门:51nod-1310] 简要题意: 有一个数组S,保证里面的数是从小到大的,而且每一个数的二进制中都没有连续的1,如:1,2,4,5,8... 给出n,然后给出n个位置,求出S数组中n个位置 ...

  5. windows下git的安装和使用

    git到底是个什么东西,我这里就不介绍了,如果大家还有不懂的,可以去百度一下的.我这里给一个介绍的网址:git简介        这里在留一个地址http://baike.baidu.com/subv ...

  6. tomcat:Could not publish to the server. java.lang.IndexOutOfBoundsException

    1.将工程加入到tomcat,报上述错误 2. run--maven build 报jar包错误: invalid LOC header (bad signature) 3.根据提示找到上述jar包, ...

  7. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  8. Debian9.5 系统配置FTP

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”.用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application ...

  9. CF19E Fairy(树上差分)

    题目描述 很久很久以前,有一个仙女叫做A.有一天一个少年B找到她,并且请求她预测他的未来.仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻.然后仙女在一张纸上画了n个点,并 ...

  10. lsof---查看你进程开打的文件

    lsof命令用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP.UDP).找回/恢复删除的文件.是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户 ...