您的位置:首页 > 编程语言 > C语言/C++

c++ primer(第五版)笔记 第六章 函数(1)

2014-08-16 00:58 246 查看
doub.h

#ifndef DOUB_H
#define DOUB_H

#include<iostream>
using std::cout;
using std::endl;
using std::cin;

int doub(int n);	//函数必须在使用前声明,可以多次声明,但只能定义一次
//如果这个函数永远不会用到,可以只有声明没有定义
//返回类型,函数名,形参列表描述了函数的接口,也称函数原型(function prototyp)

#endif


doub.cpp

#include "doub.h"

int doub(int n)	//doub 函数名, 前面的 int 是返回类型(return type), 圆括号内是形参列表(parameter list)
{
static int cnt = 0;	//局部静态变量
int i = 3;
cout << "cnt : " << cnt << endl;
cout << "i : " << i << endl;
cout << "n : " << n << endl;
++cnt;
return 2 * n + i; 	//函数体,语句块
}


find_char.h

#ifndef FIND_CHAR_H
#define FIND_CHAR_H

#include<string>
#include<iostream>
#include<initializer_list>

using std::string;
using std::cout;
using std::endl;
using std::initializer_list;

string::size_type find_char(const string &s, char c, string::size_type &occure);
void error_msg(initializer_list<string> il);
#endif //FIND_CHAR_H


find_char.cpp

#include "find_char.h"
//根据之前 const 限定类型的拷贝规则,
//我们不对 s 进行改写操作,所以定义为 const, 如果 s 是非const,则无法接受 const 实参,所以定义函数时尽量使用 const
//const char c 和 char c 在进行拷贝初始化时是一样的,顶层 const 会忽略
//occure 需要改变其值,不能设为 const
string::size_type find_char(const string &s, char c, string::size_type &occure)
{
auto ret = s.size();
for (decltype(ret) i = 0; i != s.size(); ++i)
{
if (s[i] == c)
{
if (ret == s.size())
ret = i;
++occure;
}
}
return ret;
}

/*
initializer_list 形参, 适用于实参数量未知,但全部实参的类型相同
表示某种特定类型的数组, initializer_list 类定义在 initializer_list.h
模板类,使用时必须指明所含元素的类型,不同于 vector, 其元素永远是常量值,无法改变其元素的值
*/
void error_msg(initializer_list<string> il)
{
for (auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << endl;
}


main.cpp

#include "doub.h"
#include "find_char.h"
#include<cstddef>

//可以通过2个可选形参将命令选项传达给程序
//argv 是一个数组,其元素是指向 c 风格字符串的指针,尾后指针保证为0;argc 表示 argv 中字符串的数量
int main(int argc, char **argv)
{
/*
函数调用时完成2个工作,
一是隐式定义形参并用实参初始化,
二是将控制权转移给被调用函数(called function),主调函数(calling function)暂时中断
当遇到 return 语句时,调用函数结束执行,同样执行2个工作
一是返回 return 中的值
二是将控制权转移给调用函数

形参与实参:根据位置一一对应,数量和类型都要匹配
可以定义空形参列表,如果需要兼容 c 语言,使用 void
同表达式的运算一样,标准并未定义实参的求值顺序
任何 2 个形参都不能重名,函数体最外层作用域的局部变量也不可以和形参重名

返回类型:不能是数组或函数,但可以是指向他们的指针,特殊一类类型 void 表示不返回任何值
*/

/*
局部变量(local variable):定义在块作用域内的变量,仅在块域中可见,会隐藏外层作用域的同名声明
自动对象(automatic object):对于普通局部变量的对象,当函数控制路径经过变量定义语句时创建对象,
到达所在块域末端时,销毁,这种存在于块执行期间的对象称为自动对象
局部静态对象(local static object):使用 static 关键字将自动对象定义为局部静态对象,
当函数控制路径经过变量定义语句时创建对象,直到程序终止才结束

局部静态对象如果没有显式的初始值,执行值初始化,内置类型初始化为 0
*/

int i = 0;
while (i < 10)
{
int res = doub(i);	//调用函数 doub,返回值用来初始化 res
cout << "res : " << res << endl;
++i;
}

/*
参数传递:
引用传递(passed by reference),形参是引用类型,调用时绑定实参,函数被传引用调用(called by reference)
对形参的任何操作实际上是对实参的操作

值传递(passed by value),将实参的值拷贝给形参, 函数被传值调用(called by value)
对形参的任何操作不会影响传入的实参
当形参是指针时,虽然2个指针是不同的指针的,但指向的对象是同一个

当拷贝较大的类类型或容器时,效率低,而且有些类型不支持拷贝操作,建议使用引用避免拷贝
如果不需要改变引用形参的值,最好将其声明为常量引用
引用形参可以作为返回结果的途径
*/
//string s{ "fadsjflwkejrhafbnsxfhklsjadfhl" };
//char c = 'n';
string::size_type occurs = 0, pos = 0;
//通过参数将搜索信息传入函数
//先判断下参数个数
if (argc != 3)
{
//cout << "wrong parameter! input like this : lesson_6_1.exe abcdefgdafadljljl f" << endl;
error_msg({"wrong parameter!","input like this : lesson_6_1.exe abcdefgdafadljljl f","exit"});	//initializer_list 类需使用初始化列表传入
return 0;
}
pos = find_char(argv[1], *argv[2], occurs);
cout << "pos : " << pos << "; occurs : " << occurs << endl;

/*
数组形参,因为数组不可以进行拷贝,当我们使用数组名时,其实是指向数组第一个元素的指针

1>使用标记指定数组长度,多用于 c 风格字符串,有一个明显的空字符结尾
void print(const char *cp)
{
if(cp)
while(*cp)	//以空字符作为标志
cout << *cp++;
}

2>使用标准库规范,首指针,尾后指针
void print(const int *begin, const int *end)
{
while(begin != end)
cout << *begin++;
}

3>显式定义一个表示数组大小的形参
void print(const int ai[], size_t size)
{
for(size_t i = 0; i != size; ++i)
cout << ia[i];
}

4>数组引用形参,这种写法写死了维度
void print(const int (&ra)[10])
{
for(auto i : ra)
cout << i << endl;
}

5>多维数组形参,指明一个维度的大小
void print(const int (*pa)[3], size_t rowsize)
{
for(size_t i = 0; i < rowsize; ++i)
{
for(auto i : *pa)
cout << i << endl;
++pa;
}
}
*/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: