函数声明仅含函数名、返回类型和参数类型,以分号结尾;定义则包含函数体。未声明或签名错误导致LNK2019错误;调用前须声明或定义,否则报“未声明”;按值传递不改变实参,引用/指针可修改原变量;返回值类型须严格匹配;inline建议展开,constexpr要求编译期可求值;链接错误多因声明定义不一致、头文件未包含或签名细微差异。

函数声明和定义的语法差异
声明只告诉编译器函数名、返回类型和参数类型,不包含函数体;定义则必须包含完整实现。漏掉声明或写错签名会导致 LNK2019(未解析的外部符号)错误。
- 声明示例:
int add(int a, int b);—— 分号结尾,放在头文件或源文件顶部 - 定义示例:
int add(int a, int b) { return a + b; }—— 有花括号和具体逻辑 - 如果在调用前没声明也没定义(比如函数写在
main()后面),编译会报‘add’ was not declared in this scope
调用函数时传参和返回值处理
C++ 默认按值传递,形参修改不影响实参;想改原变量得用引用或指针。返回值类型必须和声明严格一致,否则触发隐式转换或编译失败。
- 基本调用:
int result = add(3, 5);—— 注意括号不能省,add不加括号是函数地址 - 传引用避免拷贝:
void swap(int& a, int& b),调用时直接写swap(x, y) - 返回局部变量没问题(C++17 起 guaranteed copy elision),但别返回局部数组指针或引用
内联函数和 constexpr 函数的区别
inline 是建议编译器展开函数以减少调用开销,不改变语义;constexpr 表示函数可在编译期求值,但要求参数和逻辑都满足常量表达式约束。
- 加
inline的函数可定义在头文件里,避免LNK2005重复定义错误 -
constexpr int square(int x) { return x * x; }允许写int arr[square(4)];(长度为 16) - 但
constexpr函数里不能有std::cout、new、非 const 变量赋值等运行期操作
常见链接错误和调试线索
函数定义和声明不匹配、忘记实现、跨文件未正确包含头文件,都会导致链接阶段失败。错误信息里带 LNK(MSVC)或 undefined reference to(GCC/Clang)就是典型信号。
立即学习“C++免费学习笔记(深入)”;
- 检查是否忘了写函数体:声明有分号,定义却漏了花括号和
{} - 确认头文件被
#include且路径正确;用#pragma once或卫哨宏防止重复包含 - Windows 下类成员函数若在 .cpp 里定义,记得加上类名限定:
MyClass::myMethod() { ... }
函数签名里的 const 修饰、引用符、默认参数值,哪怕多一个空格都可能让链接器找不到对应实现。实际项目中,优先把声明放头文件、定义放源文件,比全塞在一个文件里更容易排查问题。


















