本文参考 : C++ Primer (第四版)  7.2.4及 16.1.5 相关章节

GeekBand 侯捷老师,学习笔记

开发环境采用:VS2013版本

关键问题一、传递引用与传指针、传值的区别?

值传递 (pass by value),指针传递(pass by pointer),当发生函数调用时,需要给形参分配存储单元、当传递是对象时,要调用拷贝构造函数。

而且指针最后析构时,要处理内存释放问题。

引用传递(pass by refenrence),在内存中没有产生形参。效率大大提高!也不用处理指针的析构问题。

通过以上分析,我们设计程序时应该尽量使用引用,少利用指针。如果非得强调类似,”值传递,如”char 类型只有一个字节,请君左转,屏幕右上角有个红叉“

关键问题二:如何传递引用

那么,传递不了指针,我们传递数组怎么样?首先看下下面的简易代码:(C++ Primer 7.2.4)

#include "stdafx.h"
#include<iostream>
using namespace std;
void PrintValues(const int ia[])
{
for (int i = ; i != ; i++)
{
cout << ia[i] << endl;
}
} int _tmain(int argc, _TCHAR* argv[])
{
int j[] = { , };
PrintValues(j);
return ;
}

这里因为编译器忽略了为任何数组形参指定长度,所以会造成数组内存越界问题。

而且,数组有二个特性,影响作用在数组上的函数:一是不能复制数组,二是使用数组名时, 数组名会自动指向其第一个元素的指针。因为不能复制,所以无法编写使用数组类型的形参,数组会自动转化为指针。

我们验证下,将Void PrintValues(const int ia[10])改为 Void PrintValues(const int *ia),结果与上图一致,这里就不贴了。

那么怎么解决这个问题呢?

方案一:显示传递表示数组大小的形参

#include "stdafx.h"
#include<iostream>
using namespace std;
void PrintValues(const int *ia,int size)
{
for (int i = 0; i != size; i++)
{
cout << ia[i] << endl;
}
} int _tmain(int argc, _TCHAR* argv[])
{
int j[] = { 0, 1 };
PrintValues(j,sizeof(j)/sizeof(*j));
return 0;
}

  

此方法虽然可以解决问题,但并不是我们需要的,这部分代码看不出来区别,但工程庞大后,使用引用要比指针高效,所以我们还是要利用引用的特性来解决这个问题。

将数组形参可声明为数组的引用,如果形参是数组的引用,编译器会传递数组的引用本身

我们再修改下代码:如下

#include "stdafx.h"
#include<iostream>
using namespace std; void PrintValues( int (&ia)[2])
{
for (int i = 0; i != 2; i++)
{
cout << ia[i] << endl;
}
} int _tmain(int argc, _TCHAR* argv[])
{
int j[2] = { 0, 1 };
PrintValues(j);
return 0;
}

  

结果显示,与pass by pointer方法结果一致,但是这里有一个缺陷,这里面 int (&ia)[2],编译器要检查数组实参和形参的大小。扩展性太差!

最终采用非类型模板解决这个问题,代码如下:
#include "stdafx.h"
#include<iostream>
using namespace std; template<class T,int N>
void PrintValues( T (&ia)[N])
{
for (int i = ; i != N; i++)
{
cout << ia[i] << endl;
}
} int _tmain(int argc, _TCHAR* argv[])
{
int j[] = { , };
PrintValues(j);
return ;
}

结果如图:

通过以上分析, 可以采用非类型模板形参传递中来解决效率问题。

												

[GeekBand] C++ 基础知识一 ——通过引用传递数组的更多相关文章

  1. (转)2.4.1 基础知识--添加服务引用与Web引用的区别

    <Web服务开发学习实录>第2章构建ASP.NET Web服务,本章我们将学习创建Web服务的各种方法,并重点对使用Visual Studio创建ASP.NET Web服务和修改Web服务 ...

  2. PHP面试 PHP基础知识 一(引用变量)

    PHP引用变量 常见引用变量面试题: 什么是引用变量? 在PHP中用什么符号定义引用变量? 考点:PHP的引用变量的概念及定义方式 概念:在PHP中引用意味着用不用的名字访问同一个变量内容     定 ...

  3. [GeekBand] C++ 基础知识之 The Big Three

    本文是GeekBand课程体系中,侯捷老师讲课内容的部分内容总结. 参考书籍如下:Effitive C++ C++ Primer 第五版 http://blog.csdn.net/lwbeyond/a ...

  4. 1.3 Python基础知识 - 用户交互及传递参数

    一.用户交互 用户交互方面,每种开发语言都有不同的方式,例如shell语言用的是,“read -p "What is  your name ? " ”.python中是什么样子的呢 ...

  5. C基础知识(5):指针--传递指针给函数&返回指针的函数

    下面从3个代码例子分别讲述以下2个知识点: (1) 传递指针给函数(参数类型为指针) (2) 返回指针的函数(返回类型为指针) #include <stdio.h> // 传递指针给函数& ...

  6. Java基础知识学习(一)--引用

    1.概念 如果一个变量的类型为类类型,而非基本类型,那么该变量就叫做引用:   2.对象引用 new Person(); 如上,代表创建了一个对象,但也仅仅是创建了,并没有办法去访问它.   为了访问 ...

  7. JavaScript基础知识整理(1)数组

    第一:创建. 1,var arr= new Array(); //数组为空.长度为0. arr[0]="apple"; arr[1]="orange"; arr ...

  8. Java基础知识强化105:打印数组的方法总结

    1. 使用for循环打印数组. 2. 使用Arrays工具类,将数组转化为有序的List打印出来. 3. 使用Arrays工具类,使用Arrays.toString()输出数组内容. 上面三种方法打印 ...

  9. java基础知识(三)之数组

    声明数组: 语法:数据类型[ ] 数组名://例:int[ ] scores;  或者 数据类型 数组名[ ]://例:int scores[ ];分配空间 语法:数组名 = new 数据类型 [ 数 ...

随机推荐

  1. 【MongoDB】The connection between two tables

    In mongoDB, there are two general way to connect with two tables. Manual Connection and use DBRef 1. ...

  2. IIS7性能优化

    http://www.03389.com/BLOG/user1/qq66565841/archives/2014/2014112143553.html IIS7性能优化 IIS7 优化-网站请求并发数 ...

  3. golang matrix

    package main import ( "fmt" "go.matrix-go1" //比较有名的关于Matrix在golang中的方法库 "st ...

  4. 洛谷 P1230 智力大冲浪

    洛谷 P1230 智力大冲浪 题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的?! ...

  5. 洛谷 P1727 计算π

    P1727 计算π 题目背景 <爱与愁的故事第二弹·compute>第一章. 题目描述 中秋至,博饼声铿锵不断.爱与愁大神兴致勃勃地到学校博饼,结果抱回家的只有一秀二举.爱与愁大神十分生气 ...

  6. 【例题 6-11 UVA-297】Quadtrees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 发现根本不用存节点信息. 遇到了叶子节点且为黑色,就直接覆盖矩阵就好(因为是并集); [代码] #include <bits/ ...

  7. 关于mysql事务行锁for update实现写锁的功能

    关于mysql事务行锁for update实现写锁的功能 读后感:用切面编程的理论来讲,数据库的锁对于业务来说是透明的.spring的事务管理代码,业务逻辑代码,表锁,应该是三个不同的设计层面. 在电 ...

  8. Java Lock Example – ReentrantLock(java锁的例子)

    Welcome to Java Lock example tutorial. Usually when working with multi-threaded environment, we use ...

  9. Angular7环境搭建报错

    昨天写的2019年Angular7——安装搭建路由方法不太正统,今天又去翻了下angular官网,跟着上面的环境搭建与部署走了一遍 从安装@angular/cli命令行工具开始 本篇主要记录下搭建过程 ...

  10. 每日技术总结:setInterval,setTimeout,文本溢出,小程序,wepy

    前言: 项目背景:vue,电商,商品详情页 1.倒计时,倒计到0秒时停止 data () { return { n: 10 } }, created () { let int = setInterva ...