[toc]
分离式编译
文件目录下有 main.cpp
、animal.cpp
、animal.hpp
,如何使用分离式编译:
g++ -c main.cpp animal.cpp # 对源文件进行汇编,生成.o文件的机器码
g++ main.o animal.o -o main # 对机器码部分进行链接,得到可执行文件
数组形参
void print(const int[10])// 这里的维度表示我们期望数组含有多少元素,实际不一定
main: 处理命令行选项
int main(int argc,char *argv[]){
}
第一个形参 argc 代表数组中字符串的个数,第二个形参是一个数组,它的元素是指向C 风格字符串的指针,获取命令行参数如下:
int main(int argc,char *argv[]){
string str;
for(size_t i = 0;i < argc;++i){
str = argv[i];// C风格字符串指针,转string
cout << str;
}
}
含有可变形参的函数
- 如果所有的实参类型相同,可以传递一个名为
initializer_list
的标准库类型; - 如果实参的类型不同,我们可以编写一种特殊的函数,可变参数模板。
- C++还有一种特殊的形参类型(即省略符),可以用它传递可变数量的实参。这种功能一般只用于C函数交互的接口程序。
initializer_list
是一种标准库类型,用于表示特定类型的值的数组,同时,initializer_list
对象中的元素永远是常量,我们无法修改 initializer_list
对象中的值。
int Sum(initializer_list<int> lst){
int sum = 0;
for(auto i : lst){
sum += i;
}
return sum;
}
int main(int argc,char *argv[]){
int output = Sum({1,2,3,4,5,6});
cout << output << endl;
}
返回对象引用和指针
需要注意,一般的返回值是创建一个临时量进行返回,而如果函数返回引用,则该引用仅是它所引对象的一个别名。
不要返回局部变量的引用和指针,因为局部变量会在函数结束之后释放,因此返回的引用和指针都是未定义的!
同时引用返回的是左值,也就是说返回的是一个对象可以被赋值或者初始化。
char &get_val(string &str,string::size_type ix){
return str[ix];
}
int main(){
string s("a value");
cout << s << endl;
get_val(s,0) = 'A';
cout << s << endl;
}
返回数组指针或者数组引用
注意区分,指针数组、数组指针、数组引用、指针函数、函数指针
原始定义
string (*fun())[10];
string (&fun())[10];
使用类型别名
using string_arr = string[10];
string_arr *fun();
string_arr &fun();
C++ 11尾置返回类型
auto fun()->string(&)[10];
使用decltype
string str[10];
decltype(str) *fun();
内联函数
inline int fun(const string &str);
内联函数会在函数所在的地方进行展开,不过内联只是向编译器发出这个请求,编译器可以忽略该请求。一般来说,小型经常用到的函数可以使用内联。
内联函数可以在程序中多次定义,内联函数通常定义在头文件中。
调试帮助
-
assert,需要包含头文件
<cassert>
,表达式如下:int i = 0; assert(i != 0);
当表达式为假的时候,就输出错误并终止程序。
-
NDEBUG
用来屏蔽调试的信息
函数指针
函数指针指的是一个指针指向一个函数,该函数包括形参类型和数量、返回类型,这些都必须匹配。
bool lengthCompare(const string &str1, const string &str2);
bool (*pf) (const string &str1,const string &str2);// 声明一个函数指针
bool decltype(lengthCompare)* (const string &str1,const string &str2);// 使用 decltype
using f = bool (const string &str1,const string &str2);
f* pf = nullptr;