[GeekBand] C++ 基础知识一 ——通过引用传递数组
本文参考 : 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++ 基础知识一 ——通过引用传递数组的更多相关文章
- (转)2.4.1 基础知识--添加服务引用与Web引用的区别
<Web服务开发学习实录>第2章构建ASP.NET Web服务,本章我们将学习创建Web服务的各种方法,并重点对使用Visual Studio创建ASP.NET Web服务和修改Web服务 ...
- PHP面试 PHP基础知识 一(引用变量)
PHP引用变量 常见引用变量面试题: 什么是引用变量? 在PHP中用什么符号定义引用变量? 考点:PHP的引用变量的概念及定义方式 概念:在PHP中引用意味着用不用的名字访问同一个变量内容 定 ...
- [GeekBand] C++ 基础知识之 The Big Three
本文是GeekBand课程体系中,侯捷老师讲课内容的部分内容总结. 参考书籍如下:Effitive C++ C++ Primer 第五版 http://blog.csdn.net/lwbeyond/a ...
- 1.3 Python基础知识 - 用户交互及传递参数
一.用户交互 用户交互方面,每种开发语言都有不同的方式,例如shell语言用的是,“read -p "What is your name ? " ”.python中是什么样子的呢 ...
- C基础知识(5):指针--传递指针给函数&返回指针的函数
下面从3个代码例子分别讲述以下2个知识点: (1) 传递指针给函数(参数类型为指针) (2) 返回指针的函数(返回类型为指针) #include <stdio.h> // 传递指针给函数& ...
- Java基础知识学习(一)--引用
1.概念 如果一个变量的类型为类类型,而非基本类型,那么该变量就叫做引用: 2.对象引用 new Person(); 如上,代表创建了一个对象,但也仅仅是创建了,并没有办法去访问它. 为了访问 ...
- JavaScript基础知识整理(1)数组
第一:创建. 1,var arr= new Array(); //数组为空.长度为0. arr[0]="apple"; arr[1]="orange"; arr ...
- Java基础知识强化105:打印数组的方法总结
1. 使用for循环打印数组. 2. 使用Arrays工具类,将数组转化为有序的List打印出来. 3. 使用Arrays工具类,使用Arrays.toString()输出数组内容. 上面三种方法打印 ...
- java基础知识(三)之数组
声明数组: 语法:数据类型[ ] 数组名://例:int[ ] scores; 或者 数据类型 数组名[ ]://例:int scores[ ];分配空间 语法:数组名 = new 数据类型 [ 数 ...
随机推荐
- Akka边学边写(4)-- MiniRPG
前面几篇文章用Akka写了HelloWorld和EchoServer,为了更进一步学习Akka,本文将会实现一个非常小的RPG游戏server:MiniRPG. 游戏逻辑 由于是迷你RPG,所以逻辑非 ...
- golang sort
package main import ( "fmt" "strings" "sort" ) type Animals []string f ...
- js面向对象2--原型
一.原型和原型对象 函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址. 所有对象都有__proto__属性, 所有的__proto ...
- python序列中是否包含某个元素
http://outofmemory.cn/code-snippet/9098/python-list-contains-with-in-not-in theList = ['a','b','c'] ...
- 【习题 6-9 UVA - 127】"Accordian" Patience
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 链表模拟即可. 1pile不能加s... [代码] #include <bits/stdc++.h> using nam ...
- 【CS Round #46 (Div. 1.5) C】Set Subtraction
[链接]h在这里写链接 [题意] 一开始有n个数字,然后有一个数字X,把每个数字都减去X,又生成N个新的数字. 然后把这2*N个数字混在一起. 告诉你这2*N个数字是什么.让你复原出原来的N个数字,以 ...
- amazeui学习笔记--css(基本样式3)--文字排版Typography
amazeui学习笔记--css(基本样式3)--文字排版Typography 一.总结 1.字体:amaze默认非 衬线字体(sans-serif) 2.引用块blockquote和定义列表:引用块 ...
- 微信支付v2开发(7) 告警通知
本文介绍微信支付中如何获得告警通知. 一.告警通知 为了及时通知商户异常,提高商户在微信平台的服务质量.微信后台会向商户推送告警通知,包括发货延迟.调用失败.通知失败等情况,通知的地址是商户在申请支付 ...
- Loadrunner--关联详解
当录制脚本时,VuGen会拦截client端(浏览器)与server端(网站服务器)之间的对话,并且通通记录下来,产生脚本.在VuGen的Recording Log中,您可以找到浏览器与服务器之间所有 ...
- 具体解释。。设计模式5——DAO。。studying
设计模式5--DAO ★ 场景和问题 在Java程序中,常常须要把数据持久化.也须要获取持久化的数据,可是在进行数据持久化的过程中面临诸多问题 (如:数据源不同.存储类型不同.供应商不同.訪问方式不同 ...