一、函数定义函数是一段可重复使用的代码块用来完成特定任务。在 C 中函数定义包含以下几个部分1.返回值类型函数返回的数据类型可以是内置类型、类类型、指针或引用无返回则写 void。2.函数名标识函数的名称遵循标识符命名规则。3.参数列表逗号分隔的形参声明可为空写 void 或留空。4.函数体花括号内的语句实现具体功能。示例计算两个整数之和的函数#includeiostream#includevectorintadd(inta,intb);intmain(){intaddNumadd(1,2);printf(add(1, 2)的值为:%d,addNum);return0;}intadd(inta,intb){returnab;}二、函数声明函数原型函数声明告诉编译器函数的名称、返回值类型及参数类型不包含函数体以分号结束。作用允许在定义之前调用函数或者跨文件使用函数。通常放在头文件中。#includeiostream// 函数声明原型intadd(int,int);// 参数名可省略保留类型即可intmain(){std::coutadd(3,4)std::endl;// 在定义前调用合法return0;}// 函数定义intadd(inta,intb){returnab;}定义与声明的区别1.声明仅提供接口信息不分配执行代码2.定义包含函数体决定函数的行为3.一个函数可有多次声明但只能有一次定义单一定义规则 ODR。三、参数传递方式C 函数参数的传递机制主要包括 值传递、指针传递、引用传递。理解它们的区别是写出正确、高效代码的关键。1. 值传递形参获得实参的副本在函数内对形参的修改不影响外部的实参。#includeiostream#includevectorvoidSwapByValue(intx,inty);intmain(){inta10;intb20;SwapByValue(a,b);// a 仍为 10b 仍为 20printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByValue(intx,inty){inttempx;xy;ytemp;// 只交换了副本}特点1.实参到形参发生拷贝适合小型对象如 int、double。2.大型对象如 std::vector拷贝开销大应避免值传递。3.函数内部对形参的修改不影响原对象天然安全。2. 指针传递将实参的地址作为值传给指针形参。函数内可通过解引用操作原对象。#includeiostream#includevectorvoidSwapByPointer(int*x,int*y);intmain(){inta10;intb20;SwapByPointer(a,b);// a 为 20b 为 10printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByPointer(int*x,int*y){inttemp*x;*x*y;*ytemp;// 通过地址修改了实参}特点1.传递的是地址值仅拷贝一个地址通常 4/8 字节避免大对象拷贝。2.可修改指针所指对象也可用 const int* 指向只读对象。3.指针可为空nullptr调用者必须保证指针有效或被调函数需检查空指针。4.适合需要“可选”参数允许不传递对象的场景或与 C 风格接口交互。3. 引用传递引用是对象的别名传递引用不会产生拷贝直接操作原对象。#includeiostream#includevectorvoidSwapByReference(intx,inty);intmain(){inta10;intb20;// 无需取地址SwapByReference(a,b);// a 为 20b 为 10printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByReference(intx,inty){inttempx;xy;ytemp;// 直接修改实参}特点1.语法简洁像值传递一样使用没有解引用开销。2.引用必须初始化不能为空通常比指针更安全。3.对引用的操作即是对原对象的操作。4.是传递大型对象的首选方式尤其配合 const。三种传递方式对比传递方式是否拷贝原对象能否修改实参是否可能为空典型用途值传递拷贝整个对象否不可能小型不可变参数指针传递拷贝地址4/8字节是非 const 时是可传 nullptrC 接口、可选参数、需要改变指向引用传递不拷贝是非 const 时不可能大型对象、输出参数、运算符重载四、函数重载函数重载允许在同一作用域内定义多个同名函数只要它们的参数列表不同。参数列表不同的含义1.参数个数不同2.参数类型不同3.参数顺序不同针对不同类型返回值类型不参与重载解析仅返回类型不同无法构成重载。示例不同类型的打印函数#includeiostream#includevectorvoidprint(inti);voidprint(doubled);voidprint(conststd::strings);intmain(){print(10);// 调用 print(int)print(3.14);// 调用 print(double)print(hello);// 调用 print(const std::string)hello 可转换为 string}voidprint(inti){std::cout整数: istd::endl;}voidprint(doubled){std::cout双精度: dstd::endl;}voidprint(conststd::strings){std::cout字符串: sstd::endl;}重载决议编译器根据实参类型寻找最佳匹配规则大致为1.精确匹配实参与形参类型完全相同。2.提升匹配如 char → int、float → double。3。标准转换匹配如 int → double、派生类指针→基类指针。4.用户定义转换如转换构造函数、类型转换运算符。注意事项与常见陷阱值传递与引用传递重载可能产生歧义#includeiostream#includevectorvoidf(intx);voidf(intx);intmain(){inta1;f(a);f(a);return0;}voidf(intx){x10;printf(f(int x):%d,x);}voidf(intx){x10;printf(f(int x):%d,x);}编译时报错有多个 重载函数 “f” 实例与参数列表匹配仅靠 const 区分引用参数是合法的且常用来区分读写版本#includeiostream#includevectorvoidg(constintx);// 接受 const 对象、右值voidg(intx);// 接受非 const 左值intmain(){inta1;constintb12;g(a);std::coutstd::endl;g(b);return0;}voidg(constintx){printf(g(int x):%d,x);}voidg(intx){printf(g(int x):%d,x);}带有默认参数时避免产生不同重载间的调用模糊例如 void h(int a, double b 0.0) 和 void h(int a) 同时存在调用 h(5) 将报错。#include iostream#include vector// 带有默认参数的版本voidh(inta,doubleb0.0){std::couth(int, double) called: aa, bbstd::endl;}// 单参数重载版本voidh(inta){std::couth(int) called: aastd::endl;}intmain(){inta5;h(a);return0;}编译时报错E0308 有多个 重载函数 “h” 实例与参数列表匹配。顶层 const 不影响重载void f(int) 和 void f(const int) 视为同一签名因为值传递时顶层 const 被忽略。但 const 引用或指针则属于不同签名void f(int*) 和 void f(const int*) 是不同的。演示“底层 const 影响重载”应该删除值传递版本只保留指针和引用重载#includeiostream// 指针重载底层 const 决定不同签名voidf(int*p){std::coutf(int*) called, *p (p?*p:0)std::endl;}voidf(constint*p){std::coutf(const int*) called, *p (p?*p:0)std::endl;}// 引用重载底层 const 决定不同签名voidf(intr){std::coutf(int) called, r rstd::endl;}voidf(constintr){std::coutf(const int) called, r rstd::endl;}intmain(){// ---------- 指针重载调用演示 ----------inta10;constintb20;f(a);// 传入 int*匹配 f(int*)f(b);// 传入 const int*匹配 f(const int*)// 若需要传递空指针必须显式转换以消除歧义f(static_castint*(nullptr));// 调 f(int*)f(static_castconstint*(nullptr));// 调 f(const int*)// ---------- 引用重载调用演示 ----------intx100;constinty200;f(x);// x 是 int 左值匹配 f(int)f(y);// y 是 const int 左值匹配 f(const int)f(300);// 300 是右值只能绑定到 const 引用匹配 f(const int)return0;}
C++——6.函数基础:定义、声明、参数传递(值、指针、引用)、重载.
一、函数定义函数是一段可重复使用的代码块用来完成特定任务。在 C 中函数定义包含以下几个部分1.返回值类型函数返回的数据类型可以是内置类型、类类型、指针或引用无返回则写 void。2.函数名标识函数的名称遵循标识符命名规则。3.参数列表逗号分隔的形参声明可为空写 void 或留空。4.函数体花括号内的语句实现具体功能。示例计算两个整数之和的函数#includeiostream#includevectorintadd(inta,intb);intmain(){intaddNumadd(1,2);printf(add(1, 2)的值为:%d,addNum);return0;}intadd(inta,intb){returnab;}二、函数声明函数原型函数声明告诉编译器函数的名称、返回值类型及参数类型不包含函数体以分号结束。作用允许在定义之前调用函数或者跨文件使用函数。通常放在头文件中。#includeiostream// 函数声明原型intadd(int,int);// 参数名可省略保留类型即可intmain(){std::coutadd(3,4)std::endl;// 在定义前调用合法return0;}// 函数定义intadd(inta,intb){returnab;}定义与声明的区别1.声明仅提供接口信息不分配执行代码2.定义包含函数体决定函数的行为3.一个函数可有多次声明但只能有一次定义单一定义规则 ODR。三、参数传递方式C 函数参数的传递机制主要包括 值传递、指针传递、引用传递。理解它们的区别是写出正确、高效代码的关键。1. 值传递形参获得实参的副本在函数内对形参的修改不影响外部的实参。#includeiostream#includevectorvoidSwapByValue(intx,inty);intmain(){inta10;intb20;SwapByValue(a,b);// a 仍为 10b 仍为 20printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByValue(intx,inty){inttempx;xy;ytemp;// 只交换了副本}特点1.实参到形参发生拷贝适合小型对象如 int、double。2.大型对象如 std::vector拷贝开销大应避免值传递。3.函数内部对形参的修改不影响原对象天然安全。2. 指针传递将实参的地址作为值传给指针形参。函数内可通过解引用操作原对象。#includeiostream#includevectorvoidSwapByPointer(int*x,int*y);intmain(){inta10;intb20;SwapByPointer(a,b);// a 为 20b 为 10printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByPointer(int*x,int*y){inttemp*x;*x*y;*ytemp;// 通过地址修改了实参}特点1.传递的是地址值仅拷贝一个地址通常 4/8 字节避免大对象拷贝。2.可修改指针所指对象也可用 const int* 指向只读对象。3.指针可为空nullptr调用者必须保证指针有效或被调函数需检查空指针。4.适合需要“可选”参数允许不传递对象的场景或与 C 风格接口交互。3. 引用传递引用是对象的别名传递引用不会产生拷贝直接操作原对象。#includeiostream#includevectorvoidSwapByReference(intx,inty);intmain(){inta10;intb20;// 无需取地址SwapByReference(a,b);// a 为 20b 为 10printf(a的值为:%d\n,a);printf(b的值为:%d,b);return0;}voidSwapByReference(intx,inty){inttempx;xy;ytemp;// 直接修改实参}特点1.语法简洁像值传递一样使用没有解引用开销。2.引用必须初始化不能为空通常比指针更安全。3.对引用的操作即是对原对象的操作。4.是传递大型对象的首选方式尤其配合 const。三种传递方式对比传递方式是否拷贝原对象能否修改实参是否可能为空典型用途值传递拷贝整个对象否不可能小型不可变参数指针传递拷贝地址4/8字节是非 const 时是可传 nullptrC 接口、可选参数、需要改变指向引用传递不拷贝是非 const 时不可能大型对象、输出参数、运算符重载四、函数重载函数重载允许在同一作用域内定义多个同名函数只要它们的参数列表不同。参数列表不同的含义1.参数个数不同2.参数类型不同3.参数顺序不同针对不同类型返回值类型不参与重载解析仅返回类型不同无法构成重载。示例不同类型的打印函数#includeiostream#includevectorvoidprint(inti);voidprint(doubled);voidprint(conststd::strings);intmain(){print(10);// 调用 print(int)print(3.14);// 调用 print(double)print(hello);// 调用 print(const std::string)hello 可转换为 string}voidprint(inti){std::cout整数: istd::endl;}voidprint(doubled){std::cout双精度: dstd::endl;}voidprint(conststd::strings){std::cout字符串: sstd::endl;}重载决议编译器根据实参类型寻找最佳匹配规则大致为1.精确匹配实参与形参类型完全相同。2.提升匹配如 char → int、float → double。3。标准转换匹配如 int → double、派生类指针→基类指针。4.用户定义转换如转换构造函数、类型转换运算符。注意事项与常见陷阱值传递与引用传递重载可能产生歧义#includeiostream#includevectorvoidf(intx);voidf(intx);intmain(){inta1;f(a);f(a);return0;}voidf(intx){x10;printf(f(int x):%d,x);}voidf(intx){x10;printf(f(int x):%d,x);}编译时报错有多个 重载函数 “f” 实例与参数列表匹配仅靠 const 区分引用参数是合法的且常用来区分读写版本#includeiostream#includevectorvoidg(constintx);// 接受 const 对象、右值voidg(intx);// 接受非 const 左值intmain(){inta1;constintb12;g(a);std::coutstd::endl;g(b);return0;}voidg(constintx){printf(g(int x):%d,x);}voidg(intx){printf(g(int x):%d,x);}带有默认参数时避免产生不同重载间的调用模糊例如 void h(int a, double b 0.0) 和 void h(int a) 同时存在调用 h(5) 将报错。#include iostream#include vector// 带有默认参数的版本voidh(inta,doubleb0.0){std::couth(int, double) called: aa, bbstd::endl;}// 单参数重载版本voidh(inta){std::couth(int) called: aastd::endl;}intmain(){inta5;h(a);return0;}编译时报错E0308 有多个 重载函数 “h” 实例与参数列表匹配。顶层 const 不影响重载void f(int) 和 void f(const int) 视为同一签名因为值传递时顶层 const 被忽略。但 const 引用或指针则属于不同签名void f(int*) 和 void f(const int*) 是不同的。演示“底层 const 影响重载”应该删除值传递版本只保留指针和引用重载#includeiostream// 指针重载底层 const 决定不同签名voidf(int*p){std::coutf(int*) called, *p (p?*p:0)std::endl;}voidf(constint*p){std::coutf(const int*) called, *p (p?*p:0)std::endl;}// 引用重载底层 const 决定不同签名voidf(intr){std::coutf(int) called, r rstd::endl;}voidf(constintr){std::coutf(const int) called, r rstd::endl;}intmain(){// ---------- 指针重载调用演示 ----------inta10;constintb20;f(a);// 传入 int*匹配 f(int*)f(b);// 传入 const int*匹配 f(const int*)// 若需要传递空指针必须显式转换以消除歧义f(static_castint*(nullptr));// 调 f(int*)f(static_castconstint*(nullptr));// 调 f(const int*)// ---------- 引用重载调用演示 ----------intx100;constinty200;f(x);// x 是 int 左值匹配 f(int)f(y);// y 是 const int 左值匹配 f(const int)f(300);// 300 是右值只能绑定到 const 引用匹配 f(const int)return0;}