目录结构:

contents structure [-]

1.简介

通常函数包括形参,函数名,函数主体,函数返回值。下面的案例展示了c++函数使用的基本语法规则:

int add(int,int);//add函数的声明

int main(int argc,char *argv[]){
  int res = add(,);
return ;
}
//add函数的定义
int add(int a,int b){
return a+b;
}

也可以不用写add函数的声明,直接把的add函数的定义写在main函数的上面:

int add(int a,int b){//add函数的定义
return a+b;
}
int main(int argc,char *argv[]){
  int res = add(,);
return ;
}

2.可变形参的函数

c++支持可变形参的函数,可以使用initializer_list来实现或是省略符来实现。

2.1 initializer_list形参

如果函数的实参数量未知,但是全部的实参类型都相同,那么就可以使用initializer_list类型的形参。在使用initilizer_list类型之前,必需先引用<initilizer_list>头文件。

initializer_list是一种模板类型,应此在使用时必需说明所含元素的类型,例如:

initializer_list<string> ls; //initializer_list元素中的类型是string
initializer_list<int> li; //initializer_list元素中的类型是int

注意:initializer_list对象中的元素值永远是常量,我们无法改变initializer_list对象中元素的值。

#include <iostream>
#include <initializer_list>
using namespace std; void error_msg(initializer_list il){
for(auto beg=il.begin(); beg != il.end(); beg++)
cout << *beg << " ";
cout << endl;
}
int main(int argc,char *argv[]){
  error_msg({"error message 1","error message 2"});//调用error_msg函数
return ;
}

2.2 省略符形参

省略符形参只能用在形参列表的最后一个位置

例如:

#include <iostream> /*cout,endl*/
#include <cstdarg> /*va_list,va_start,va_end*/ int sum(int count, ...) { //格式:count代表参数个数, ...代表n个参数
va_list ap; //声明一个va_list变量
va_start(ap, count); //第二个参数表示形参的个数并且只能是参数列表中最后一个被命名了的参数。 int sum = ;
for (int i = ; i < count; i++) {
sum += va_arg(ap, int); //第二个参数表示形参类型
} va_end(ap); //用于清理 return sum;
}
int main(int argc,char **argv){
cout << sum(,1.1,2.2,3.3,4.4,5.5) << endl;
return ;
}

3.main函数处理命令行选项

main函数是应用程序的入口函数,它有如下几种形式:

int main(){}
int main(int argv,char *argv[]){}
int main(int argv,char **argv){}

第一种形式main函数不接收任何参数。

第二种形式main函数,其中第一个形参argc表示数组的大小;第二个形参argv表示一个数组,它的元素是指向C风格字符串的指针。

int main(int argc,char *argv[]){
for(decltype(argc) index=; index<argc; index++)
cout << argv[index] << " ";
cout << endl;
return ;
}

第三种形式main函数,argv是一个指针,指向一个char*类型。

int main(int argc,char **argv){
for(decltype(argc) index=; index<argc; index++)
cout << (*argv++) << " ";
cout << endl;
return ;
}

若将上面的程序命名为test.cpp,在编译成功后,使用如下命令运行:./test how are you
输出结果为:

./test how are you

从结果中可以看出,"./test"并不是我们想输出的(我们本意是想输出"how are you")。应此需要注意,main函数中,实际的参数应该从下标1开始。

4.函数指针与函数引用

函数指针,顾名思义就是指向函数的指针。同理,函数引用就是引用函数的引用。

例如:

bool (*pf)(const string&,const string&);

pf前面有一个*,因此pf是指针;右侧是形参列表,表明pf指向函数;再观察左侧,发现函数的返回值类型是布尔值。因此pf就是一个指向函数的指针,其中函数具有两个const string&形参,返回值是bool类型。

注意:
如果pf是这样的话

bool *pf(const string&,const string&)

那么pf就不是函数指针了,这种情况下pf表示为一个函数,函数具有两个const string&类型的形参,和一个bool指针类型的返回值。

当把函数名作为一个值使用时,该函数自动地转化为指针。同时还能直接使用指向函数的指针调用该函数,无须提前解引用。

#include <iostream> /*cout,endl*/
using namespace std;
int compare(const string& a,const string& b){
return a.compare(b);
}
int compare(const int& a,const int& b){
return a - b;
}
//定义一个函数,其形参为另一个函数
void test1(int (*p)(const string&,const string&)){
p("hello","world");
};
//test2和test1是等价声明,函数类型会自动转化为指向函数的指针
void test2(int p(const string&,const string&)){
p("hello","world");
}; //test3返回一个函数指针,该指针具有两个int类型的形参,返回值类型为void
void (*test3())(int,int){
}
//test4和test3是等价声明
auto test4()-> void (*)(int,int){
} void (*test5( int (*p)(const int&,const int&) ))(int,int){
p(1,2);
return ;
} int main(int argc,char **argv){
int (*pf)(const string&,const string&);//声明一个函数指针
pf=;//pf不指向任何函数
pf = compare;//pf指向 int compare(const string&,const string&) int res = pf("hello","world");//调用pf所知指函数,无需提前解引用 int (&rpf)(const int&,const int&) = compare;//声明一个引用,初始化为compare(compare有两个重载函数,这里引用形参为两个的const int&的函数) int res = rpf(,);//调用rpf所引用的函数 test1(compare);//传递方法作为实参,也可以参数函数指针作为实参。 void (*p)(int,int) = test3();//返回一个函数指针 p = test5(rpf);//接受一个函数指针,返回一个函数指针。rpf会自动转化为函数指针
return ;
}

5.inline内联函数

inline函数被称为内联函数,就是将它在每个调用的节点上“内联地”展开。

在函数定义的时候加上inline关键字,这样就成为内联函数了。

#include <iostream>
#include <string>
using namespace std;
//shoterString函数接受两个const string类型参数,返回一个const string&类型的数据,同时该函数是内联函数。
inline const string & shoterString(const String s1,const String s2){
return (s1.size() < s2.size() ? s1 : s2);
}
int main(int argc,char *argv[]){
string s1 = "hello";
string s2 = "world";
//编译时转化为cout << (s1.size() < s2.size() ? s1 : s2) << endl;
cout << shoterString(s1,s2) << endl;
}

一般来说,内联机制用于规模较小,流程直接,频繁调用的函数。很多编译器都不支持内联递归函数。

6.Constexpr函数

constexpr是c++11新标准添加的关键字,该关键字主要用于提供程序的运行效率,使用constexpr指定的值和函数能够在编译时进行计算,比如下面的product()将会在编译时被计算:

constexpr int product(int x, int y)
{
return (x * y);
}
int main()
{
//在编译后,会直接转化为 const int x = 200;
const int x = product(, );
cout << x;
return ;
}

输出结果为:

200

使用constexpr函数有以下几点约束:
1.在c++11中,一个constexpr函数只能有一个return语句。c++14标准中,允许超过一个return语句。
2.constexpr函数应该只引用常量全局变量
3.constexpr函数能够调用其他constexpr函数,不能调用非constexpr函数。
4.constexpr函数不能返回void类型,还有一些操作符比如(++v,--v)都不允许出现在constexpr函数。

【C++】C++中的函数的更多相关文章

  1. Oracle 中 decode 函数用法

    Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...

  2. mysql中now()函数的使用,还有oracle的sysdate,可能埋下的坑

    mysql中now()函数的使用,还有oracle的sysdate 在需求中如果系统中药添加当前操作的时间那么很简单的一个操作在写sql的时候直接在这个字段对应的位置写上now()函数就可以了,这样就 ...

  3. 程序代码中退出函数exit()与返回函数return ()的区别

    程序代码中退出函数exit()与返回函数return ()的区别   exit(0):正常运行程序并退出程序:   exit(1):非正常运行导致退出程序:   return():返回函数,若在主函数 ...

  4. mysql中find_in_set()函数的使用

    首先举个例子来说: 有个文章表里面有个type字段,它存储的是文章类型,有 1头条.2推荐.3热点.4图文等等 .现在有篇文章他既是头条,又是热点,还是图文,type中以 1,3,4 的格式存储.那我 ...

  5. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...

  6. Bash 是如何从环境变量中导入函数的

    在上文中曾说到: 所谓的环境变量的真实面目其实就是个任意字符串 Bash 在启动时会将 environ 数组中包含 = 号的字符串导入成为自己的变量 Bash 在启动外部命令时会将自己内部标记为环境变 ...

  7. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  8. PHP中spl_autoload_register()函数的用法

    spl_autoload_register (PHP 5 >= 5.1.2) spl_autoload_register — 注册__autoload()函数 说明 bool spl_autol ...

  9. matlab中patch函数的用法

    http://blog.sina.com.cn/s/blog_707b64550100z1nz.html matlab中patch函数的用法——emily (2011-11-18 17:20:33) ...

  10. $.getJSON('url',function(data){}) 中回调函数不执行

    $.getJSON('url',function(data){}) 中回调函数不执行 url 中的 json 格式不正确 ,浏览器返回并没有报错 {'湖北':[114.11438,30.849429] ...

随机推荐

  1. Nightmare Ⅱ HDU - 3085 (双向bfs)

    Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were tra ...

  2. POJ 2418 Hardwood Species 【Trie树】

    <题目链接> 题目大意: 给你一堆字符串,让你按字典序输出他们出现的频率. 解题分析: 首先,这是Trie数词频统计的题目,以Trie树的边储存字母,节点存储以该节点结尾的链所代表的字符串 ...

  3. 使用pdfBox实现pdf转图片,解决中文方块乱码等问题

    一.引入依赖 <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox ...

  4. type__列表

  5. bzoj3033: 太鼓达人 欧拉路径

    题目链接 bzoj3033: 太鼓达人 题解 对于k-1位点,k位二进制位边,将点的转移连起来 每个点的入度和出度相等并且全部是偶点 只需要在这个图中找字典序最小的欧拉回路 可以贪心地找字典序较小的边 ...

  6. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  7. 树形动态规划(树状DP)小结

    树状动态规划定义 之所以这样命名树规,是因为树形DP的这一特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系.利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的记忆化搜索的 ...

  8. python之模块4

    1 模块与包 1.1 模块的定义 什么是模块 模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 为什么使用模块 在退出python解释器然后重新进入,之前定义的函数 ...

  9. JS_高程4.变量,作用域和内存问题(2)执行环境及作用域

    1.执行环境:执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为, 每个执行环境都有一个与之相关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 2.全局执行环境: 最外围的 ...

  10. Tips_方格拼图效果

    用原生的javascript实现方格拼图效果 1.新建文件夹 代码如下: 01.html <!DOCTYPE html> <html lang="en"> ...