C++工程实战入门笔记4-函数(一)
实参、形参、函数调用、函数返回值
bool View(int index)
{cout << "call view(" << index << ")" << endl;return true;
}
void Testvoid()
{cout << "Testvoid()" << endl;
}
void SetSize(int w, int h)//形参
{cout << w << ":" << h << endl;cout << "形参地址:" << (long long)&w << ":" << (long long)&h << endl;
}
int main()
{auto re = View(100);cout << re << endl;Testvoid();int w{ 1920 };//实参int h{ 1080 };//实参cout <<"实参地址:"<< (long long)&w << ":" << (long long)&h << endl;SetSize(w, h);system("pause");
}
return:类似break,return后边的代码不会运行
int GetWidth()
{int w = 1024;//栈区变量return w;//复制w变量的值给返回值变量,return类似break,return后边的代码不会运行w++;//不会运行
}
全局变量、静态全局变量、局部变量、静态局部变量
//全局变量:进入main函数就申请空间
int gcount = 0;//生命周期是全局,作用域仅限于本文件
//静态全局变量:进入main函数就申请空间
static int scount = 0;int TestVer(int x, int y)//局部变量x y
{//局部静态变量 生命周期,第一次运行时申请空间static int count{ 0 };gcount++;//可以访问全局变量scount++;//本文可以访问静态全局变量count++;cout << "gcount = " << gcount << endl;cout << "scount = " << scount << endl;cout << "count = " << count << endl;int re = x + y;//局部变量rereturn re;
}
int main()
{TestVer(100, 200);TestVer(200, 300);TestVer(300, 400);system("pause");
}
全局变量
#include <iostream>int globalVar = 10; // 全局变量void func() {std::cout << "全局变量: " << globalVar << std::endl;globalVar++;
}int main() {func(); // 输出: 全局变量: 10func(); // 输出: 全局变量: 11return 0;
}
静态全局变量
// File1.cpp
static int staticGlobalVar = 20; // 静态全局变量,只能在File1.cpp中访问void func() {std::cout << "静态全局变量: " << staticGlobalVar << std::endl;
}// File2.cpp
extern int staticGlobalVar; // 错误!无法访问其他文件的静态全局变量
局部变量
#include <iostream>void func() {int localVar = 30; // 局部变量std::cout << "局部变量: " << localVar << std::endl;localVar++;
}int main() {func(); // 输出: 局部变量: 30func(); // 输出: 局部变量: 30 (每次调用都重新初始化)return 0;
}
静态局部变量
#include <iostream>void func() {static int staticLocalVar = 40; // 静态局部变量std::cout << "静态局部变量: " << staticLocalVar << std::endl;staticLocalVar++;
}int main() {func(); // 输出: 静态局部变量: 40func(); // 输出: 静态局部变量: 41 (保持状态)func(); // 输出: 静态局部变量: 42return 0;
}
使用建议与最佳实践
- 优先使用局部变量:减少副作用,提高代码可维护性
- 谨慎使用全局变量:可能导致难以追踪的bug和代码耦合
- 静态局部变量用于保持状态:当需要在函数调用间保持状态时使用
- 静态全局变量用于文件内部共享:限制作用域,避免命名冲突
- 多线程环境注意事项:全局和静态变量需要适当的同步机制
指针和指针变量
- 指针=内存地址
- 指针变量=存放指针的变量
p是x的地址
*p=10
p=1001
int main()
{int x{ 10 };cout << "=======================x======================" << endl;cout << "x的值:"<<x << endl;//值cout << "x的地址:" << &x << endl;//指针system("pause");
}
int main()
{int x{ 10 };cout << "=======================x======================" << endl;cout << "x的值:"<<x << endl;//值cout << "x的地址:" << &x << endl;//指针//定义指针变量int* p{ &x };//p存放了x的内存地址cout <<"===========================p======================" << endl;cout<<"*p:" << *p << endl;cout << "p:" << p << endl;cout << "&p:" << &p << endl;system("pause");
}
引用
int main()
{int x{ 10 };cout << "=======================x======================" << endl;cout << "x的值:" << x << endl;//值cout << "x的地址:" << &x << endl;//指针int& ref{ x };//必须初始化,ref变成了x的别名cout << "=======================ref======================" << endl;cout << "ref:" << ref << endl;cout << "&ref:" << &ref << endl;//引用本身不占内存,效率更高ref++;cout << "========================ref++====================" << endl;cout << "ref+1:" << ref << endl;cout << "&ref不变:" << &ref << endl;cout << "x的值+1:" << x << endl;cout << "x的地址不变:" << &x << endl;system("pause");
}
指针和引用作为参数,减少复制
//指针和引用作为参数,减少复制
void TestParaPtr(int *x, const int*y)
{cout << "TestParaPtr:" << *x << ":" << *y << endl;cout << "指针TestParaPtr addr:\t" << x << ":" << y << endl;
}
void TestPara(int x, const int y)
{cout << "TestPara:" << x << ":" << y << endl;cout << "变量直接传递TestPara addr:" << &x << ":" << &y << endl;
}void TestParaRef(const int &x, const int &y)
{cout << "TestParaRef:" << x << ":" << y << endl;cout << "引用TestParaRef addr:\t" << &x << ":" << &y << endl;
}int main()
{int x = 1920;int y = 1080;cout << "x y main函数赋值后addr:\t" << &x << ":" << &y << endl;TestPara(x, y); TestParaPtr(&x, &y);TestParaRef(x, y);system("pause");
}
按值传递 (Pass by Value)
行为:函数获得实参的一个副本。效果:在函数内部修改参数,不会影响外部的原始变量。开销:如果实参是大型结构体或类对象,创建副本的成本很高。
按引用传递 (Pass by Reference)
行为:函数获得实参的一个别名(引用)或地址(指针)。效果:在函数内部修改参数,直接影响外部的原始变量。开销:无论对象多大,传递的都是一个固定大小的地址(如 8 字节),效率极高。
关于const的使用—最佳实践与最终选择指南
优先使用 const 引用:当你不需要修改参数,只想避免拷贝时。这是默认选择,尤其是对于类对象和大型结构体。void func(const MyClass& obj);使用非 const 引用:当你需要修改参数,且该参数是必须提供的。void swap(int& a, int& b);
使用引用和指针,实现返回多参数
//使用引用和指针,实现返回多参数
//指针
void GetPosPtr(int* x, int* y)
{*x = 800;*y = 600;
}//引用
void GetPosRef(int& x, int& y)
{x = 640;y = 480;
}int main()
{int x = 1920;int y = 1080;GetPosPtr(&x, &y);cout << "GetPosPtr:" << x << ":" << y << endl;GetPosRef(x, y);cout << "GetPosRef:" << x << ":" << y << endl;system("pause");
}
按值返回 (Return by Value)
行为:返回的是对象的一个副本。优点:最安全。调用者获得一个独立的全新对象,与原对象无关。缺点:可能产生拷贝开销(但编译器有 RVO/NRVO 优化)。
按引用/指针返回 (Return by Reference/Pointer)
行为:返回的是原始对象的“别名”或“地址”,而非副本。优点:零拷贝,极致高效。允许修改函数外部的对象。致命缺点:你必须绝对确保返回的对象在调用者使用它时仍然存活! 否则会导致未定义行为(通常是程序崩溃)。