【C++ 初阶】命名空间 / 输入输出 / 缺省参数 / 函数重载

【C++ 初阶】命名空间 / 输入输出 / 缺省参数 / 函数重载

在这里插入图片描述

🎬 博主名称键盘敲碎了雾霭
🔥 个人专栏: 《C语言》《数据结构》《C++》

⛺️指尖敲代码,雾霭皆可破


在这里插入图片描述

文章目录

一、namespace

1.1 namespace的引入

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,
C语言错误示范:

#include<stdio.h>#include<stdlib.h>int rand =6;intmain(){printf("%d", rand);}
在这里插入图片描述


c语言项目类似下面程序这样的命名冲突是普遍存在的问题,C++引入namespace就是为了更好的解决
C++优化

#include<stdio.h>namespace m {int rand =6;}intmain(){printf("%d", m::rand);}

1.2 namespace的定义

  • 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对即可,中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
namespace m {int a =6;intAdd(int a,int b){return a + b;}structNode{structNode* next;int val;};}
  • namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量
  • C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
  • namespace只能定义在全局,当然他还可以嵌套定义。
namespace m {namespace n {int a =0;int b =9;}int c =6;}
  • 项目工程中多文件中定义的同名namespace会认为是一个namespace,不会冲突。
  • C++标准库都放在一个叫std(standard)的命名空间中。

1.3 namespace使用

编译查找一个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找
我们要使用命名空间中定义的变量/函数,有三种方式:

  • 指定命名空间访问,项目中推荐这种方式。
std::cout 
  • using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。
using m::a;
  • 展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。
usingnamespace std;

二、输入输出

#include<iostream>intmain(){int a =0;double b =0; std::cin >> a >> b; std::cout << a <<" "<< b << std::endl;}
  • 是Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输出对象
  • std::cin是istream类的对象,它主要面向窄字符(narrow characters(of type char))的标准输入流
  • td::cout是ostream类的对象,它主要面向窄字符的标准输出流
  • std::endl是一个函数,流插入输出时,相当于插入一个换行字符加刷新缓冲区。
  • <<是流插入运算符,>>是流提取运算符。(C语言还用这两个运算符做位运算左移/右移)
  • C++的输入输出可以自动识别变量类型,不需要像printf/scanf输入输出时那样,需要手动指定格式
  • cout/cin/endl等都属于C++标准库,C++标准库都放在一个叫std(standard)的命名空间中,所以要通过命名空间的使用方式去用他们。
  • 一般日常练习中我们可以using namespace std,实际项目开发中不建议using namespace std
  • VS上<iostream>间接包含<stdio.h>,也可以使用printf和scanf
    在io需求比较高的地方,如部分大量输入的竞赛题中,加上以下3行代码:
#include<iostream>usingnamespace std;intmain(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);}

三、缺省参数

  • 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。
#include<iostream>usingnamespace std;intAdd(int a =1,int b =2){return a + b;}intmain(){ cout <<Add(4,3)<< endl; cout <<Add()<< endl;return0;}
  • 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。并且带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参
#include<iostream>usingnamespace std;intAdd(int a ,int b =2){return a + b;}intmain(){ cout <<Add(4,3)<< endl; cout <<Add(2)<< endl;return0;}

函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值

usingnamespace std;intAdd(int a,int b=2);intAdd(int a ,int b){return a + b;}intmain(){ cout <<Add(4,3)<< endl; cout <<Add(2)<< endl;return0;}

四、函数重载

C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调用就表现出了多态行为,使用更灵活。C语言是不支持同一作用域中出现同名函数的

4.1 参数类型不同

#include<iostream>usingnamespace std;voidAdd(int a ,int b){ cout << a + b << endl;}voidAdd(double a ,double b){ cout << a + b << endl;}intmain(){Add(3,5);Add(4.0,7.0);}

4.2 参数个数不同

#include<iostream> using namespace std;voidfuc(){ cout <<"haha"<< endl;}voidfuc(int a){ cout <<"hehe"<< endl;}intmain(){fuc();fuc(4);}

4.3 参数类型顺序不同

#include<iostream>usingnamespace std;voidfuc(int a,char b){ cout <<"haha"<< endl;}voidfuc(char b,int a){ cout <<"hehe"<< endl;}intmain(){fuc(1,'0');fuc('0',4);}

4.4 错误点

  • 返回值不同不能作为重载条件,因为调用时也无法区分
  • 有缺省参数时,会报错,存在歧义,编译器不知道调用谁
usingnamespace std;voidf1(){ cout <<"f()"<< endl;}voidf1(int a =10){ cout <<"f(int a)"<< endl;}

解决方法

#include<iostream>usingnamespace std;voidf1(){ cout <<"f()"<< endl;}namespace m {voidf1(int a =10){ cout <<"f(int a)"<< endl;}}intmain(){f1(); m::f1();}

五、引用

5.1 引用的概念和定义

类型&引用别名=引用对象;

usingnamespace std;intmain(){int a =0;int& b = a;int& c = b;int& d = a; c++; cout << a <<" "<< b <<" "<< c<<" "<< d << endl;return0;}
在这里插入图片描述

5.2 引用的特性

  • 引用在定义时必须初始化
int& b;//错误写法
  • 一个变量可以有多个引用
  • 引用一旦引用一个实体,再不能引用其他实体(不能改变指向)
#include<iostream>usingnamespace std;intmain(){int a =10;int& b = a;int c =20; b = c;//赋值操作,不能引用其他实体 cout << a <<" "<< b<<" "<< c << endl;}

5.3 引用的使用

  • 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。
#include<iostream>usingnamespace std;typedefint STDataType;typedefstructStack{ STDataType* a;int top;int capacity;}ST;voidSTInit(ST& rs,int n =4){ rs.a =(STDataType*)malloc(n *sizeof(STDataType)); rs.top =0; rs.capacity = n;}voidSTPush(ST& rs, STDataType x){if(rs.capacity == rs.top){int newcapacity =(rs.capacity ==0?4: rs.capacity *2); STDataType*ptr=(STDataType*)realloc(rs.a,sizeof(STDataType)* newcapacity);if(ptr ==NULL){perror("realloc");return;} rs.capacity = newcapacity;} rs.a[rs.top++]= x;}int&STTop(ST& rs){return rs.a[rs.top-1];}voidSTDestroy(ST& rs){if(rs.a ==NULL){return;}free(rs.a); rs.a =nullptr; rs.capacity = rs.top =0;}intmain(){ ST rs;STInit(rs);STPush(rs,1);STPush(rs,2);STPush(rs,3); cout <<STTop(rs)<< endl;STTop(rs)=10; cout <<STTop(rs)<< endl;return0;}
  • 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引l用(如Java)是有很大的区别的,除了用法,最大的点,C++引用定义后不能改变指向,Java的引用可以改变指向。

5.4 const引用

  • 可以引l用一个const对象,但是必须用const引l用。const引l用也可以引l用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大。
#include<iostream>intmain(){int a =1;constint& b = a;constint c =1;//只读不写constint& d = c;}
  • 在类型转换中会产生临时对象存储中间值,而C++规定临时对象具有常性,所以这里就触发了权限放大,必须要用常引用才可以。
double a =1.23;constint& b = a;
  • 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++中把这个未命名对象叫做临时对象。(函数返回值也有临时对象,具有常性)
int a =0;int b =2;constint& c = a + b;

六、指针和引用

  • 用是一个变量的取别名不开空间,指针是存储一个变量地址,要开空间
  • 用在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
  • 用在初始化时引用一个对象后,就不能再引用其他对象;而指针可以在不断地改变指向对象。(不能代替指针)
  • 可以直接访问指向对象,指针需要解引用才是访问指向对象
  • sizeof中含义不同,引用结果为引l用类型的大小,但指针始终是地址空间所占字节个数
  • 指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全一些。(相对安全,当变量在函数里面定义,却把引用返回来,类似于空指针)

七、inline

  • 用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈顿了,就可以提高效率
  • inline适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上inline也会被编译器忽略。
inlinevoidSwap(int& a,int& b){int tmp = a; a = b; b = tmp;}
  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了inline目的就是替代C的宏函数
  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。并且编译器在展开时找不到函数体。

vs编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下以下两个地方。

在这里插入图片描述


在这里插入图片描述


更改前:

在这里插入图片描述


更改后:

在这里插入图片描述

八、nullptr

8.1 问题引入

本想通过fuc(NULL)调用指针版本的fuc(int*)函数,但是由于NULL被定义成0,调用了fuc()因此与程序的初衷相悖。

#include<iostream>usingnamespace std;voidfuc(int a){ cout <<"haha"<< endl;}voidfux(int* a){ cout <<"haha"<< endl;}intmain(){fuc(0);fuc(NULL);fuc((void*)0);}

8.2 原因分析

C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。

#ifndefNULL#ifdef-_cplusplus#defineNULL0#else#defineNULL((void*)0)#endif#endif

8.3 解决方法

C++11中引入nullptrnullptr是一个特殊的关键字,nullptr是一种特殊类型的字面量,它可以转换成任意其他类型的指针类型(void*)在C++中不能隐式转换,在C语言中可以。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型。

fuc(nullptr);

文章结语

感谢你读到这里~我是「键盘敲碎了雾霭」,愿这篇文字帮你敲开了技术里的小迷雾 💻

如果内容对你有一点点帮助,不妨给个暖心三连吧👇
👍 点赞 | ❤️ 收藏 | ⭐ 关注
(听说三连的小伙伴,代码一次编译过,bug绕着走~)

你的支持,就是我继续敲碎技术雾霭的最大动力 🚀

🐶 小彩蛋:

 /^ ^\ / 0 0 \ V\ Y /V / - \ / | V__) || 

摸一摸毛茸茸的小狗,赶走所有疲惫和bug~我们下篇见 ✨

Read more

LLaMA-Factory微调多模态大模型Qwen3-VL

LLaMA-Factory微调多模态大模型Qwen3-VL

LLaMA-Factory微调多模态大模型Qwen3-VL 目录 LLaMA-Factory微调多模态大模型Qwen3-VL 1. 显卡驱动 2. 模型微调 3. 模型导出 4. 模型部署:vLLM服务 5. 测试效果 1. 显卡驱动 * 显卡型号:NVIDIA GeForce RTX 3090 24G * 显卡驱动:NVIDIA-SMI 535.171.04             * CUDA: 12.2 ,Driver Version: 535.171.04   微调Qwen3-VL-2B模型,至少需要12G显存 2. 模型微调 项目采用大型语言模型工厂(LLaMA-Factory)对大模型微调,目前可支持Qwen3 / Qwen2.5-VL / Gemma 3 / GLM-4.1V / InternLM

By Ne0inhk
【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent

【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent

【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent 1.背景 作为一名长期关注人工智能发展的内容创作者,我经常需要撰写关于AI技术、应用趋势和产品体验的文章。然而,在实际写作过程中,常常会遇到灵感枯竭、结构混乱、表达不够精准等问题。有时候写到一半才发现逻辑断层,或者内容重复,甚至忘记了一些关键知识点。 为了解决这些痛点,我决定打造一个专属于自己的智能写作助手,取名为“文思通”——寓意“文思如泉涌,条理通达”。这个助手不仅要能帮我生成内容,更要具备结构化思维引导、逻辑梳理和语言润色的能力。 最近,我接触到一种创新的工具组合:以 Coze 平台为核心逻辑流,结合自研的思维导图 MCP 服务,可以实现从文本到可视化思维导图的自动转换。这正好解决了我在构思阶段缺乏条理的问题。而选择开发平台时,我注意到腾讯云智能体开发平台与腾讯混元大模型(Hunyuan AIGC) 的深度整合能力非常出色,支持工作流编排、插件扩展(MCP),并且提供稳定高效的推理服务。 最终,我决定采用“混元AIGC + 腾讯云智能体平台

By Ne0inhk
Qwen3.5-4B 微调实战:LLaMA-Factory 打造医疗AI助手

Qwen3.5-4B 微调实战:LLaMA-Factory 打造医疗AI助手

最近在帮一个医疗创业团队做技术支持,他们想把通用大模型改造成能回答专业医疗问题的智能助手。今天就把整个过程整理出来,希望对有类似需求的朋友有所帮助。 核心工具链:LLaMA-Factory + Qwen3.5-4B + 医疗问答数据集 Qwen3.5 是阿里最新发布的千问系列模型,4B 参数量刚好卡在"效果够用 + 显存友好"的甜蜜点;LLaMA-Factory 则是目前开源社区最成熟的微调框架,上手简单,坑也相对少。 准备工作 先说硬件要求。4B 模型用 LoRA 微调的话,一张 12GB 显存的显卡就够了(比如 RTX 4070)。如果手头只有 8GB 显存的卡,可以上 QLoRA 量化方案,牺牲一点精度换显存空间。 微调方式 4B 模型显存需求 推荐显卡 LoRA (16-bit) ~10-12 GB

By Ne0inhk
2026年高校AIGC检测新规解读:AI率多少算合格?

2026年高校AIGC检测新规解读:AI率多少算合格?

2026年高校AIGC检测新规解读:AI率多少算合格? 从2024年知网正式上线AIGC检测功能开始,短短两年时间,"AI率"已经从一个新鲜名词变成了每个毕业生必须面对的硬性指标。2026年,各高校的AIGC检测政策进一步收紧和细化,要求也越来越明确。 那么,2026年AI率到底多少才算合格?不同学校的标准差别大吗?不合格会面临什么后果?本文将对这些问题进行深入解读。 一、AIGC检测已成为毕业论文审查的标配 回顾AIGC检测在高校中的普及历程,可以用"指数级扩散"来形容: * 2024年:知网上线AIGC检测功能,少数985/211院校开始试点,大部分学校处于观望状态 * 2025年:超过60%的本科院校和80%的研究生培养单位将AIGC检测纳入论文审查流程 * 2026年:AIGC检测基本实现全覆盖,包括专科院校在内的绝大部分高等教育机构都已建立相关制度 这一进程的背后,是教育部在2025年初发布的《关于加强高等学校学位论文学术诚信管理的指导意见》,其中明确提到"鼓励各高校引入人工智能生成内容检测机制,将AIGC检测作为论文质量保障的重要环节"。 虽然教育部没

By Ne0inhk