> 백엔드 개발 > C#.Net 튜토리얼 > 6장 C++: 함수 기본 및 응용

6장 C++: 함수 기본 및 응용

php是最好的语言
풀어 주다: 2018-08-06 10:47:13
원래의
1540명이 탐색했습니다.

6장 함수

함수는 함수를 호출하여 해당 코드를 실행하는 명명된 코드 블록입니다.

함수 기본

  • 호출 연산자(호출 연산자)를 통해 함수를 실행합니다. 그 형식은 한 쌍의 괄호입니다.

  • 함수 호출은 아래 그림과 같이 두 가지 작업을 완료합니다. 이때 주 호출 함수(호출 함수)의 실행이 일시적으로 중단되고 호출된 함수(호출 함수)가 실행을 시작합니다.

    • 함수에 해당하는 형식 매개변수를 실제 매개변수로 초기화합니다.

    • 호출된 함수로 제어권을 전달합니다.

  • return 문:

    • return 문에서 값을 반환합니다.

    • 호출된 함수에서 호출 함수로 제어를 다시 이동합니다.

로컬 개체

  • 이름 범위가 있고, 객체에는 lifetime(수명)

  • automatic object(자동 객체)이 있습니다. 객체는 함수의 제어 경로가 변수 정의문을 통과할 때 생성되고, 블록이 끝나는 시점에 소멸됩니다. 정의에 도달했습니다.

  • 부분 정적 객체: 프로그램 실행 경로가 처음 객체 정의문을 통과할 때 초기화되며, 프로그램이 종료될 때까지 소멸되지 않습니다.

    • 로컬 변수를 static로 정의하여 다음을 얻습니다. 예:
      <code> <br>//统计函数count_calls ()被调用了多少次 <br>size_t count_calls () <br>{ <br>static size_t ctr = 0;  //调用结束后,这个值仍然有效 <br>return ++ctr; <br>} <br>int main() <br>{ <br>for (size_t i = 0; i != 10; ++i) <br>cout << cout_calls() << endl; <br>return 0; <br>} <br>

函数声明

  • 也称作函数原型(function prototype)

  • 函数三要素(返回类型、函数名、形参类型)描述了函数的接口,函数声明中形参名可省略。

  • 函数应在头文件中声明,源文件中定义。

  • 分离式编译

参数传递

如果形参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝后赋给形参。
- 如果无需修改引用形参的值,最好将其声明为常量引用。

main:处理命令行选项

假设main函数位于可执行文件prog内,我们可以向程序传递下面的选项:

prog -d -o ofile data0
로그인 후 복사

这些命令通过两个可选的形参传递给main函数:

int main(int argc, char *argv[]) {...}
//或:
int main(int argc, char **argv) {...}
로그인 후 복사

当实参传给main函数之后,argv的第一个元素指向程序的名字或者一个空字符串,接下来的元素一次传递命令行提供的实参。最后一个指针只会掉元素值保证为0。
- 以上面的命令行为例:

argc = 5;argv[0] = "prog";argv[1] = "-d";argv[2] = "-o";argv[3] = "ofile";argv[4] = "data0";argv[5] = 0;
로그인 후 복사

含有可变形参的函数

  • C++11新标准提供两种方法编写能处理不同数量实参的函数:

    1. 所有实参类型相同,可以传递一个名为initializer_list的标准库类型。

    2. 实参类型不同,我们可以编写一种特殊的函数,叫做可变参数模板。

  • C++还有一种特殊的形参类型:省略符。可以用它传递可变数量的实参。这种功能一般只用于与C函数交互的接口程序。

  • initializer_list形参

    • 其类型定义在同名的头文件中

    • 提供如下操作:
      <br/>initializer_list<T> lst; //默认初始化,T类型元素的空列表 <br/>initializer_list<T> lst{a,b,c...}; <br/>//lst的元素数量和初始值一样多;lst的元素是对应初始值的副本;列表中的元素是const <br/>lst2(lst) <br/>lst2 = lst //拷贝或复制一个initializer_list对象不会拷贝列表中的元素;拷贝后,原始列表和副本元素共享 <br/>lst.size() //列表中元素的数量 <br/>lst.begin() //返回指向lst中首元素的指针 <br/>lst.end() //返回指向lst中尾元素下一位置的指针 <br/>//통계 함수 count_calls()가 호출된 횟수

      size_t count_calls()
    • {
    static size_t ctr = 0; / /호출이 완료된 후에도 이 값은 여전히 ​​유효합니다.
return ++ctr;

}

int main()
    {
  • for (size_t i = 0; i != 10; ++i)

    cout < ;< cout_calls() <<

    return 0;
  • 함수 선언

(함수 프로토타입)
  • 3 요소 함수의 (🎜반환 유형, 함수 이름, 형식 매개변수 유형 🎜)은 함수의 인터페이스를 설명하며, 함수 선언에서 형식 매개변수 이름을 생략할 수 있습니다. 🎜🎜🎜🎜함수는 헤더 파일에 선언하고 소스 파일에 정의해야 합니다. 🎜🎜🎜🎜별도 컴파일🎜🎜🎜🎜매개변수 전달🎜🎜 형식 매개변수가 참조 유형인 경우 해당 실제 매개변수에 바인딩되고, 그렇지 않으면 실제 매개변수의 값이 복사되어 형식 매개변수에 할당됩니다. . 🎜- 참조 매개변수의 값을 수정할 필요가 없는 경우 이를 상수 참조로 선언하는 것이 가장 좋습니다. 🎜🎜main: 명령줄 옵션 처리 🎜🎜main 함수가 실행 가능한 프로그램 내에 있다고 가정하면 다음 옵션을 프로그램에 전달할 수 있습니다. 🎜
    #include <cassert>assert(expr);//首先对expr求值,//如果表达式为假(即0),assert输出信息并终止程序的执行。//如果表达式为真(即非0),assert什么也不做。//例如:对一个文本进行操作的程序可能要求所给定单词的长度都大于某个阈值。assert(word.size() > threshold;
    로그인 후 복사
    로그인 후 복사
    🎜이 명령은 두 가지 선택적 형식 매개변수를 통해 main 함수에 전달됩니다. 🎜
    //如果定义了NDEBUG,#ifndef和#endif之间的代码将被忽略void print(const int ia[], aize_t size)
    {    #ifndef NDEBUG
            //_ _func_ _是编译器定义的一个局部静态变量,用于存放函数的名字,它是const char的一个静态数组。
            cerr << _ _func_ _ << "array size is " << size << endl;    #endif}
    로그인 후 복사
    로그인 후 복사
    🎜 인수가 주 함수에 전달되면 argv의 첫 번째 요소는 프로그램 이름이나 빈 문자열을 가리키고 다음 요소는 명령줄에서 제공하는 인수를 전달합니다. 마지막 포인터는 요소 값만 삭제하며 0이 보장됩니다. 🎜- 위의 명령줄을 예로 들어 보겠습니다. 🎜
    _ _FILE_ _ 存放文件名的字符串字面值
    _ _LINE_ _ 存放当前行号的整型字面值
    _ _TIME_ _ 存放文件编译时间的字符串字面值
    _ _DATA_ _ 存放文件编译日期的字符串字面值
    로그인 후 복사
    로그인 후 복사

    가변 매개변수가 있는 함수

    🎜🎜🎜 새로운 C++11 표준은 다양한 수의 실제 매개변수를 처리할 수 있는 함수를 작성하는 두 가지 방법을 제공합니다. 🎜 🎜🎜
      🎜🎜실제 매개변수는 모두 동일한 유형이며,initializer_list라는 표준 라이브러리 유형을 전달할 수 있습니다. 🎜🎜🎜🎜다양한 실제 매개변수 유형을 사용하여 가변 매개변수 템플릿이라는 특수 함수를 작성할 수 있습니다. 🎜🎜
    🎜🎜C++에는 줄임표라는 특수 매개변수 유형도 있습니다. 이를 사용하여 가변 개수의 실제 매개변수를 전달할 수 있습니다. 이 함수는 일반적으로 C 함수와 상호 작용하는 인터페이스 프로그램에만 사용됩니다. 🎜🎜🎜🎜🎜initializer_list 형식 매개변수🎜 🎜🎜🎜🎜🎜🎜 해당 유형은 동일한 이름의 헤더 파일에 정의됩니다. 🎜🎜🎜🎜다음 작업을 제공합니다. 🎜 🎜initializer_list<T> //기본값 초기화, T 유형 요소의 빈 목록 🎜initializer_list<T> lst{a,b,c...} 🎜//lst의 요소 수는 초기 값만큼 많습니다. 해당 초기 값은 목록의 요소입니다. const 🎜lst2(lst) 🎜lst2 = lst //initializer_list 개체를 복사하거나 복사하면 복사 후 목록의 요소가 복사되지 않으며 원본 목록과 복사 요소는 공유됩니다. lst.size() //목록의 요소 수 🎜lst.begin() //lst🎜lst.end()의 첫 번째 요소에 대한 포인터를 반환합니다. //마지막 요소의 다음 위치에 대한 포인터를 반환합니다. lst🎜🎜🎜🎜🎜🎜반환 유형 및 반환 문🎜🎜🎜🎜 참조는 lvalue를 반환하고 다른 반환 유형은 rvalue를 가져옵니다. 🎜🎜🎜🎜🎜목록 초기화 반환 값🎜: 새로운 C++11 표준에서는 함수가 중괄호로 둘러싸인 값 목록을 반환할 수 있다고 규정합니다. 🎜🎜🎜🎜주 함수 main🎜🎜🎜🎜의 반환 값을 사용하면 주 함수에 반환 값이 없는 것이 허용됩니다(그렇지 않은 경우 컴파일러는 암시적으로 반환 0을 삽입합니다)🎜
  • 返回0表示执行成功,其他值依机器而定。

  • 为了使返回值与机器无关,cstdlib头文件定义了两个预处理变量,分别表示成功和失败:
    <br/>return EXIT_FAILURE; <br/>return EXIT_SUCCESS; <br/>//因为它们是预处理变量,所以既不能在前面加上std::,也不能在using声明里出现。 <br/>

返回数组指针

  1. 使用类型别名
    <br/>typedef int arrT[10]; //arrT是一个类型别名,它表示的类型是含有10个整数的数组 <br/>using arrT = int[10]; //与上一句等价 <br/>arrT* func(int i); //func返回一个指向含有10个整数的数组的指针 <br/>

  2. 声明一个返回数组指针的函数,形式如下
    <br/>Type (*function(parameter_list)) [dimension] <br/>//Type表示返回的数组指针指向的数组元素类型 <br/>//dimension表示数组的大小 <br/>//例如: <br/>int (*func(int i)) [10]; <br/>

  3. 使用尾置返回类型(C++11)
    <br/>auto func(int i) -> int(*)[10]; <br/>

  4. 使用decltype
    <br/>int odd[] = {1,3,5,7,9}; <br/>int even[] = {0,2,4,6,8}; <br/>decltype(odd) *arrPtr(int i) <br/>{ <br/> return (i % 2) ? &odd : &even; //返回一个指向数组的指针 <br/>} <br/>

函数重载

如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载(overloaded)函数

  • 不允许两个函数除了返回类型外其他所有要素都相同。

  • 重载与作用域:一旦在当前作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体。

特殊用途语言特性

介绍三种函数相关的语言特性:默认实参、内联函数、constexpr函数。

默认实参

  • 调用包含默认实参的函数时,可以包含该实参,也可以省略该实参。

  • 一旦某个形参被赋予了默认值,它后面所有的形参都必须有默认值。

内联函数(inline)

调用函数一般比求等价表达式的值要慢,内联函数可避免函数调用的开销。
- 将函数指定为内联函数,通常就是将它在每个调用点上“内联地”展开。

constexpr函数

  • 函数的返回类型和所有的形参类型都得是字面值类型。

  • 函数中必须有且只有一条return语句。

  • constexpr函数被隐式地指定为内联函数。

内联函数和constexpr函数通常定义在头文件中

调试帮助

程序可以包含一些用于调试的代码,但这些代码只在开发程序时使用。当应用程序编写完成准备发布时,要先屏蔽掉调试代码。这种方法用到两项预处理功能:assert和NDEBUG。

assert预处理宏

#include <cassert>assert(expr);//首先对expr求值,//如果表达式为假(即0),assert输出信息并终止程序的执行。//如果表达式为真(即非0),assert什么也不做。//例如:对一个文本进行操作的程序可能要求所给定单词的长度都大于某个阈值。assert(word.size() > threshold;
로그인 후 복사
로그인 후 복사

NDEBUG预处理变量

  • assert的行为依赖于一个名为NDEBUG的预处理变量的状态。如果定义了NDEBUG,则assert什么也不做。默认状态下没有定义NDEBUG,此时assert将运行执行时检查。

    • 使用#define语句定义NDEBUG,从而关闭调试状态。

    • 很多编译器都提供了命令行选项使我们可以定义预处理变量。
      <br/>$ CC -D NDEBUG main.C #微软编译器中用 /D <br/>

  • 这只是调试程序的辅助手段,不能代替真正的逻辑检查,也不能代替程序本应该包含的错误检查。

  • 除了assert以外,也能使用NDEBUG编写自己的条件调试代码:

//如果定义了NDEBUG,#ifndef和#endif之间的代码将被忽略void print(const int ia[], aize_t size)
{    #ifndef NDEBUG
        //_ _func_ _是编译器定义的一个局部静态变量,用于存放函数的名字,它是const char的一个静态数组。
        cerr << _ _func_ _ << "array size is " << size << endl;    #endif}
로그인 후 복사
로그인 후 복사

除了_ _ func _ _之外,还有其它四个名字:

_ _FILE_ _ 存放文件名的字符串字面值
_ _LINE_ _ 存放当前行号的整型字面值
_ _TIME_ _ 存放文件编译时间的字符串字面值
_ _DATA_ _ 存放文件编译日期的字符串字面值
로그인 후 복사
로그인 후 복사

函数指针

bool lengthCompare(const string &, const string &);//pf指向一个函数,该函数的参数是两个const string的引用,返回值是bool类型。注意圆括号必不可少bool (*pf) (const string &, const string &);    //未初始化
로그인 후 복사

当我们把函数名作为值使用时,该函数自动地转换成指针

pf = lengthCompare;     //pf指向名为lengthCompare的函数pf = &lengthCompare;    //等价赋值语句,&是可选的
로그인 후 복사

调用该函数:

//此三个调用等价bool b1 = pf("hello", "goodbye");bool b2 = (*pf)("hello", "goodbye");bool b3 = lengthCompare("hello", "goodbye");
로그인 후 복사

参考:C++Primer第五版

相关文章:

第四章C++:表达式概念-运算符的应用

5장 C++: 명령문 소개

위 내용은 6장 C++: 함수 기본 및 응용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
c++
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿