数据结构、算法与应用c++语言描述--1.5习题总结

习题1-5:编写一个函数iota,实现a[i]=a[i]+value(0<=i<n)

思路1:这个题目看起来非常简单,就是给每一个数组元素再加上一个值就可以了。这里面涉及到了判断数组的边界,毕竟数组传给函数的时候会退化成指针。因此当然的联想到1-2习题的方式,采用引用传递的方式实现。

实现1:

template <class T>
void iota_error(T &a,const T  & value)
{// Set a[i] = a[i] + value, 0 <= i < n.
    int num=sizeof(a)/sizeof(a[0]); //为了少使用一个数组大小参数n,想到使用&a引用传递
                                    //然而马上就出了问题 将&改回*则不会出现问题
    for (int i = 0; i < num; i++)
            a[i] += value;
}

问题1:然而再调试的时候编译器却报错:
no matching function for call to 'iota_error'

查询许多网站之后仍旧没有得到结果。网上其他人的错误原因都各有不同。

解决1:我找到了习题的答案,书上给出的代码是使用值传递,这让我不解。

实现2:

template <class T>
void iota(T* a, int n, const T& value)
{// Set a[i] = a[i] + value, 0 <= i < n.
    for (int i = 0; i < n; i++)
        a[i] += value;
}

问题2:然而一方面我不理解为什么之前推荐我们用引用传递,而在这里却用的是值传递。另外一方面,我希望能够不使用参数n表示数组大小,而是利用引用的特性从数组中获得其大小。

解决2:书上给出了数组的形式参数的书写形式。

如:int a[m]或者int a[];显然前者规定了数组的大小,只能在一些情况使用。我们希望的是对于任意情况都满足。而后者其实你如果这样写,编译器是会报错的。

因此真正的解决方法是前后结合的写法。m作为一个变量来写,当然这个变量在编译器编译后会变成常量。

实现3:

template <class T,unsigned m>//数组的传递会使得其没有办法知道数组大小,必须有一个额外参数使之满足 这里使用c++primer里面使用的方法 m为非类型参数
void iota_error_corrected(T  (&a)[m], const T& value){
    for (int i = 0; i < m; i++)
        a[i] += value;
}

暂时没有解决的问题:为什么1-2习题中可以引用数组,在这里却会出问题。

我尝试过将定义修改成

void iota_error(T* &a,const T  & value)//错误 这样也是不行的
void iota_error(T (&a)[],const T  & value)//错误 说明他是一个数组,但是没有给出大小不行
void iota_error(T (&a)[5],const T  & value)//正确 给定一个具体数字表示数组大小是可以的
void iota_error(T &a)//正确 删除掉value后变成和习题1-2类似的形式又可以了

出现这些结果的原因我暂时都无法解释,我想还是因为我对c++的理解不够,我打算请教其他人这个问题,或者在之后的学习中解决这个问题。

posted @ 2017-09-30 13:19  sleep_loke  阅读(1124)  评论(0编辑  收藏  举报