C++ primer 读书笔记(8)

数组作参数

数组作为函数的形参,有两种定义方法。第一种是非引用型的定义,实际上传给函数的是指向数组首元素的指针,如下的定义是等价的

viod fun(int arr[])
void fun(int arr[10])
void fun(int *arr)

在调用参数的时候会将实参数组的指针赋值给arr,从而可以用arr加脚标获得数组元素,但实参的数组指针并没有发生改变。由于只是传入指针值,数组的大小并没有传入,上面第二种定义中的10其实意义不大,反而可能引起误解导致数组访问越界。

第二种方式就是引用型定义,形参成为数组的引用,此时同时传入数组的指针和大小,在定义中必须写上数组大小,如果实参和形参大小不一致会报错,定义如下:

void fun(int (&arr)[10])    //注意,括号是必须的,因为[]优先级高

多维数组作参数

多维数组事实上是数组的数组,例如二维数组是一位数组的数组,其数组名其实是指向以为数组的指针。所以传入多维数组的时候,一定要给出低维的大小,这样才知道指针所指的每一个元素的大小,这里的元素并不是一个简单类型,而是数组,所以定义二维数组有以下方式:

void fun(int matrix[10][10])
void fun(int (*matrix)[10])    
定义的都是指向大小为10个整型数组的指针,即指针每向下移动一次,就移动了10个int 的空间,指向下一个数组。


防止数组越界的技巧

由于不能直接给函数传递数组,所以调用函数后如果忽视了数组大小很容易产生越界访问。下面有三个避免越界的技巧:

1. 学习字符串变量,在数组结尾处放一个标记,就像字符串结尾的‘\0’,一旦访问到此,即表示到了结尾处;

2. 学习容器中iterator的用法,在给函数传递数组的首元素和尾元素的下一个位置,就像vector的begin()和end()一样,当数组指针遇到尾元素的下一个位置即停止访问;

3. 直接传入数组大小,以防止超过数组范围。


函数返回值

讲完函数的参数,我们再来看看函数的返回值。一般性的知识这里就不赘述了,讲一些我以前不知道的知识:

1. 不要返回指向局部变量的引用型返回值。我们知道函数的返回值可以定义为各种类型,引用型也不例外。当函数的返回值为非引用型时,在调用函数时会分配一个临时对象,将函数的返回值copy后赋值给这个临时对象。但当返回值为引用型时,就不会copy返回值,而是直接返回返回值本身,例如:

const string &shorterString(const string &s1, const string &s2)
{
    return s1.size()<s2.size()?s1:s2;
}

假设此时s1比s2短,函数shorterString返回的就是s1这个string对象本身。

但是这样会带来问题。如果引用的返回值是该函数的局部变量,当函数运行结束后,局部变量会被清除,这样引用型的返回值其实就不存在了,再去访问可能出错。

const string &manip(const string &s)
{
    string ret=s;
    return ret;
}

与上例不同,本例在函数内产生了局部变量ret,将s的赋值给ret后,返回ret,函数返回时并不是把ret的值再赋值给临时的string对象,而是直接返回ret这个变量本身,但是当函数运行结束后,ret会被清除,此后函数的返回值事实上就不存在了。

2. 与上面同样的道理,也不能返回指向局部变量的指针型返回值

3. 引用型返回值时Lvalue。这意味着我们可以对返回值进行赋值等操作,看下面一段程序:

char &get_val(string &str, string::size_type pos)
{
    return str[pos];
}

int main()
{
    string s="a value";
    get_val(s, 0)=‘A’;    //可以对函数返回值赋值
    cout<<s<<endl;
    return 0;
}

看起来很惊讶,实际上很容易想见,既然返回值是一个引用型,它其实就是一个变量的别名,一个变量当然是Lvalue,所以我们可以对其进行赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值