C++函数必须先声明再定义后调用,声明需在调用前、带分号、类型严格一致,参数名可省略但建议保留;默认参数仅限声明中指定;inline/static/constexpr影响链接属性而非行为。

C++ 里函数不是“定义完就能用”,得先声明、再定义、最后调用——三步缺一不可,否则编译直接报错。
函数声明写在哪?不写会报 ‘xxx’ was not declared in this scope
这是最常见卡点:你在 main() 里调用了 add(),但编译器在读到那行时根本没见过这个函数名。
解决办法就是提前告诉编译器:“后面会有个叫 add() 的函数,它接收两个 int,返回一个 int”。这叫声明,通常放在 main() 上方或头文件里。
- 声明末尾必须带分号:
int add(int a, int b); - 参数名可以省略(只留类型):
int add(int, int);,但建议写上,提高可读性 - 不能在函数体内声明另一个函数(C++ 不支持嵌套函数声明)
函数定义和声明的参数类型必须严格一致
声明写的是 double calc(double x),定义却写成 double calc(float x)?编译器会当它是两个不同函数,调用时找不到匹配项,报 no matching function for call to 'calc'。
立即学习“C++免费学习笔记(深入)”;
尤其注意指针和引用、const 修饰、模板参数这些容易被忽略的差异:
-
void foo(const std::string& s)和void foo(std::string s)是两个函数 -
int* p和int*& p类型不同,声明和定义必须完全对应 - 如果用了默认参数,只能在声明里写(通常放头文件),定义中不能再出现
调用时传参顺序、类型、数量错一个就崩
C++ 不做运行时类型推导,所有检查都在编译期。传 add(3.14, 2) 给 int add(int, int),编译器会隐式转换,但传 add("a", "b") 就直接失败。
- 实参个数必须等于形参个数(除非有默认参数或可变参数)
- 类型不匹配时,仅允许有限的隐式转换(如
int → double),std::string → const char*这类不行 - 临时对象绑定到非 const 引用会失败:
void bar(int& x); bar(5);报错,得改成const int&或传变量
inline、static、constexpr 这些关键字改的是链接属性,不是“写法装饰”
加了 inline 不代表函数一定内联,只是告诉链接器“这个定义可能在多个编译单元出现,别报重复定义”;static 让函数只在当前文件可见;constexpr 要求函数体足够简单、能在编译期求值。
-
inline函数定义通常要放在头文件里(否则其他文件看不到) -
static函数不能在别的 .cpp 里声明后调用,链接时找不到符号 -
constexpr函数若用了std::vector或动态内存,编译直接拒绝
最容易被忽略的是:声明和定义分散在不同文件时,头文件没被正确包含、或包含了两次没加 #pragma once / #ifndef,导致重复定义或未定义行为。这类问题不会立刻报错,但链接阶段会出人意料地失败。









