简洁既是美—用while语句复制数组
简洁既是美,程序员应尽量尝试编写简洁的表达式,争取用简单的代码来实现更多的功能,当然,这也要看情况了(有时候也得考虑程序运行的时间嘛)。
在阅读C++Prime Plus到while语句时有一个讲一个数组内容复制到另一个数组的例子:
//arr1 is an array if ints
int *source=arr1;
size_t sz=sizeof(arr1)/sizeof(*arr1); //number of elements
int *dest=new int[sz];
while(source!=arr1+sz)
*dest++=*source++; //copy element and increment pointers
首先初始化source和dest,并使他们各自指向所关联的数组的第一个元素。while循环条件判断是否已经到达要复制的数组的末尾。如果没有,继续执行循环。循环体只有单个语句,实现元素的复制,并对两个指针做自增操作,使他们指向对应数组的下一个元素。
此处,循环体中的语句:
*dest++=*source++;
即所说的简约。这个表达式也等价于:
{
*dest=*source;
++dest;
++source;
}
根据上述,我在编译器上编写了下面的程序:
#include<iostream>
using namespace std;
int main(){
char arr1[]="string";
char* source=arr1;
size_t sz=sizeof(arr1)/sizeof(*arr1);
char *dest=new char[sz];
while(source!=arr1+sz)
*dest++=*source++;
cout<<arr1<<endl;
cout<<dest<<endl;
cout<<"**********"<<endl;
cout<<sz<<endl;
delete []dest;
return 0;
}
程序的作用为将数组arr1复制到dest中,并输出arr1和dest。但运行的结果并不是我想的:
问题
首先,我想到的是是不是数组arr1中的内容并没有复制到dest中,所以我对程序进行了但步跟踪,最后找到了原因:
开始,我们定义了一个arr1数组,接着使用new表达式动态创建了一个数组,并返回了指向新创建对象的指针dest,接着利用source指针和
dest指针复制了元素,这看起来并没有错。但是我忽略了一点,dest是一个指向动态数组的指针而不是数组名,可是我在最后的输出时把dest指针当做
了数组名(cout<<dest<<endl;)。
让我们来看看C++ Prime Plus上是怎么描述new表达式的:new表达式动态创建对象时,只需指定其数据类型,而不必为该对象命名,取而代之的是,new表达式返回指向新创建对象的指针,我们通过该指针来访问此对象。
虽然我最后输出时的确是使用dest指针来访问我们创建的动态数组,但需要知道的是此时的dest指针指的已经不是动态数组了。
如图,在程序执行while循环之前,source和dest指针分别指向arr1和动态数组的第一个元素,但执行了while循环后两个指针如图所示,所以此时再利用dest指针来访问动态数组是不行了。
解决方法:就像书上说的,对于new表达式动态创建的对象,我们通过返回的指针来访问此对象,而在本例中dest指针充当了工作指针,从而使得dest指针最后并没有指向动态数组,这样给我们访问动态数组不方便,所以我们可以再创建一个指针来代替dest指针充当工作指针。
程序更给如下:
//…
char *dest=new char[sz];
char *dest_p=dest;
while(source!=arr1+sz)
*dest_p++=*source++;
//….
程序运行结果如下:
总结:
1、简洁既是美,作为一个程序员应尽量做到自己编写的程序短小精悍,以比较少的代码使用更大的功能,有经验的程序员非常重视简练。要不断研究类似*dest++=*source++;的代码,最后达到一目了然的地步。
2、C++中,在使用new表达式创建动态对象时,我们会利用返回的指针来访问此对象,所以应该创建一个新的指针来充当工作指针,避免原指针最后知道我们不清楚的地方而对访问此对象造成麻烦。
简洁既是美—用while语句复制数组的更多相关文章
- linq---我为你提笔序,你的美不只查询语句
LinQ百度百科对她这样解释,是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据. LINQ是Language Int ...
- 【简洁之美】裴波那切数列生成器 python
裴波那切数列可以用生成器较好的去生成,直接上代码: # 1 控制最大数字版本 def fib(max): x,y = 0,1 while y < max: yield x x,y = y,x+y ...
- 简洁之美 -约瑟夫环的python 解法
问题描述: 约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人出列:他的下一个人又从1开始报数,数到k的那个人又出列:依此规律重复下 ...
- WPF:简洁为美
(1)3行代码实现水印TextBox(Watermark TextBox) 效果图: 源代码: <Grid> <Grid.Resources> <BooleanToVi ...
- 7.21.02 switch语句
switch语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支. 语法 switch语法格式如下: switch(expression) { case value : //语句 break ...
- Java循环语句怎么用?经典排序算法见真知
Java中循环语句的使用,莫过于在排序算法中使用得最为经典. 排序算法非常的多,不过大体可以分为两种: 一种是比较排序,主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等. 另一种是非 ...
- java的if语句,少于一行可以省略大括号
我们认识的 if 语句,大概是这样的: if(条件){ 语句1; }else{ 语句2; } 如果要执行的语句少于1行,大括号是可以省略的 可以让程序更简洁和美观 if(条件){ 语句1; 语句2; ...
- SQL统计每科前三名的学生的语句
偶然在论坛看到一个网友的帖子,关于他遇到一个面试题的,网站写了很多,我看了一下,结果应该是没问题的,但是为何面试官还是不满意,我想面试官可能并不是想考你真能把这道题做出来,而是看你如何简洁的通过一个s ...
- 感受python之美,python简单易懂的小例子
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 1 简洁之美 通过一行代码,体会Python语言简洁之美 2 Python ...
随机推荐
- cassandra中对节点失败与否的探测方法, the Phi accrual Failure Dector,附论文
(1)在分布式系统中,对于某个节点是否还“活着”的探测,通常是设定一个时间的阀值,然后根据接收到的“心跳”信息的间隔,来判定这个节点是否还活着,然后返回一个bool值: 但这种做法很容易造成误判:因为 ...
- Libgdx 开发指南——目录
本系列文档选译自libgdx github项目 wiki : https://github.com/libgdx/libgdx/wiki 由于关于Libgdx的中文文档非常稀缺,因此在这里对官方Wik ...
- MVC中的自定义控件——分页
上一篇是个简单例子,这篇借分页写个升级版的例子. 不想拼html代码,因为不好修改,那写一个PartialView. @model System.Web.Mvc.PagerModel @if (Mod ...
- codeforces 706D (字典树)
题目链接:http://codeforces.com/problemset/problem/706/D 题意:q次操作,可以向多重集中增添,删除,询问异或最大值. 思路:转化为二进制用字典树存储,数字 ...
- php-访问数据库
建一个连接,造一个连接对象 $db = new MySQLi("host","username","passwd","databa ...
- 如何让LinearLayout也有类似Button的点击效果?
有的时候,我们希望LinearLayout布局也有点击的效果,这时候我们不仅需要一个作为背景的selector,还要设置一些其它属性才行: android:clickable="true&q ...
- 如何成为一名优秀的前端工程师 (share)
发现一篇不错的博文,和大家分享一下,为有志成为一名优秀前端工程师的童鞋们提供一个参考. :)~ 本文来源:http://www.biaodianfu.com/what-makes-a-good-fro ...
- oracle 跨数据库取数据
思路:先从另一个数据库里把数据取出来, 然后,把这个数据集合解析,根据这个数据集合拆分组合成一个创建oralce临时表的方法及数据的插入.紧接着就可以写sql语句进行联合查询了. 下面是具体实例的方法 ...
- uget和aria2
http://blog.csdn.net/luojiming1990/article/details/9078447 其中的aria2 -v要改成aria2c -v
- SPOJ QTREE Query on a tree
题意:给一颗n个点的树,有两种操作CHANGE i ti : 把第i条边的权变为tiQUERY a b : 问点a 到 点b 之间的边的最大权 思路:树剖处理边权.由于是边,所以只需要把边权处理到子节 ...