4,return(返回值)
非void的函数必须返回一个与声明类型匹配的值,否则会引起编译错误
return语句结束当前正在执行的函数,将控制权返回给函数的调用者,只返回一个元素,默认情况下,函数的返回值是按值传递的
*返回引用
将函数声明为返回引用,则不需要对return语句中的表达式进行复制,而是返回对象本身
函数返回的引用仅是它所指向对象的一个别名
//找出s1和s2中比较短的一个并返回其引用
const string& shorter(const string& s1, const string& s2)
{
return (s1.size() <= s2.size()) ? s1 : s2;
}
//函数返回结果时不会真正复制对象,返回的就是s1或s2本身。
#include <iostream>
#include <string>
using namespace std;
string& longerString(string &sa, string &sb){
return sa.size() > sb.size() ? sa : sb;
//返回对象本身,不进行复制
}
int main(){
string s1 = "cat",s2 = "at";
longerString(s1 , s2)[0] = 'h'; //返回字符串中的对象
//相当于s1[0] = 'h';
cout << s1 << endl;
}
返回指针和引用一定是要存在的,函数结束后内部空间被释放。
5,函数重载
重载函数,名字相同,功能类似,参数不同
一般用是定义容易区分的函数重载(型参数目不同或类型不同)
调用函数时,如果存在多个重载函数,编译器将根据函数调用中指定的实参进行选择
void print(const int *b, const int *e){...}
void print(const int ia[], size_t size){...}
void print(const char *cp){...}
int arr[5] = {1, 2, 3, 4, 5};
print("Hello!");
//调用print(const char *)
print(arr, 5);
//调用print(const int*, size_t)
print(begin(arr), end(arr));
//调用print(const int*, const int*)
6,作用域和存储类别
对象的生存期
是指程序执行过程中对象存在的时间
对象的生存期与对象的作用域和存储类别密切相关
名字的作用域
程序的一段区域,名字的作用域指的是该名字可以在哪些程序文本区使用。
对象的存储类别
创建对象时分配内存空间的方式和内存空间的类型
*静态变量
声明为static的局部对象是静态存储的
static对象在控制流程第一次到达其定义点时被初始化,如果没有提供初始值,就被自动初始化为0值
在函数的后续调用中,初始化语句被跳过
静态对象的值在函数的多次调用之间保持有效,生存期会延续到整个程序结束,但它的作用域仍然是局部的
#include <iostream>
using namespace std;
void fun(){
static int sval = 5; //第一次调用函数时初始化
int ival = 5;
sval++;
ival++;
cout<<"sval="<<sval<<" ival="<<ival<<endl;
}
int main(){
for (int i =0 ; i < 3; i ++) fun();
}
//sval值是8,ival一直是6
*register变量(寄存器)
在可能的情况下,编译器会将该对象装载到机器的寄存器中;如果不能,仍在内存中存储
不能对寄存器变量取地址
*存储类别和存储空间分配(概念长文)
1.静态存储
2.自动存储
3.动态存储
1
静态分配是指在全局静态存储区为变量分配内存空间
编译时就分配了内存地址(相对地址)
在程序开始执行时变量就占用内存,直到程序结束时变量才释放内存
静态存储的对象
全局对象、namespace作用域对象、文件作用域对象、用static 和extern 声明的对象、局部static对象
静态存储对象的生存期从被创建持续到程序结束
2
自动分配指在程序的运行栈存储区中为变量临时分配内存空间
程序运行后,在变量作用域开始时由系统自动为变量分配内存,在作用域结束后即释放内存
自动存储的对象
自动局部对象、register 局部对象
动存储的对象的生存期持续到创建它们的块结束时为止
3
动态分配是指利用被称为堆(heap)的内存块为变量分配内存空间
堆在静态存储区和栈之外,又称为自由存储区
动态分配的对象
完全由程序本身控制动态空间的分配与释放
用new 创建动态对象,用delete 结束这类对象的生存期
堆中分配的对象没有名字,需要通过指针间接操纵
由new 分配的动态对象不再使用时必须用delete 释放,否则会造成内存泄漏