指针也能达到这种效果
发布时间:2025-06-24 07:58:08 作者:北方职教升学中心 阅读量:652
b、类域,域影响的是变量/函数/类型的出处的逻辑, 有了域隔离(不同的域可以同名,同一个域不可以定义同一个东西),名字冲突的问题就解决了。C++是在C语言之上发展出来的,在C++的编译器里是兼容C语言的,两者可以混合使用。
- 第一步找到vs编译器的 项目,点击
- 点击项目内容的最后一个选项。namespace关键字,是针对名称冲突而出现的。
局部域和全局域除了会影响编译时的查找逻辑(先局部查找,然后全局查找),还会影响变量的生命周期。
std::cin
,是 istream 类的对象,主要面向窄字符的标准输出,与C语言的不同,它不需要使用占位符,可以自动识别任意类型的变量。函数、
#include <iostream>using namespace std;namespace hx{ int rand = 0; void Print() { cout << "哈哈哈" << endl; } struct Node { int val; struct Node* next; };}int rand = 10;int main(){ int rand = 10; cout << ::rand << endl; cout << rand << endl; hx::Print(); struct hx::Node node; return 0;}
展开命名空间
使用using将名称空间全部成员展开,在项目中不推荐,名称之间的冲突很大。进行引用。
//#define ADD(a, b) a + b;//#define ADD(a, b) (a + b)//#define ADD(a, b) ((a) + (b))// 为什么不能加分号? 例如if语句调用加分号的ADD函数// 为什么要加外⾯的括号,为什么要加⾥⾯的括号?
C语言debug版本默认不展开inline。
- 不管是什么类型的数据,都会被转换为字符流,进行输入输出
std::endl
(end line),是一个函数,流插入、
所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象, C++中把这个未命名对象叫做临时对象。内联函数一般用于代码短小,频繁带哦用的函数。
- 参数列表不同
- 返回类型可以相同,也可以不同,只凭借返回类型无法实现函数重载
- 作用域必须在同一个
#include <iostream>int Add(int left, int right){ return left + right;}double Add(double left, double right){ return left + right;}int main(){ Add(1, 2); Add(1.2, 5.2); return 0;}
这里实际上调用了两个函数
这里同时使用了函数重载和缺省参数,语法上没问题,当直接调用 test()
,编译器直接傻眼了不知道到的用那个函数,有歧义。指针也能达到这种效果。
- 全缺省参数,给全部形参缺省值,C++规定必须从左到右依次给实参,不能跳跃给实参
#include <iostream>using namespace std;int Add(int a = 1, int b = 2, int c = 3){ return a + b + c;}int main(){ cout << Add() << endl; cout << Add(10) << endl; cout << Add(10, 20) << endl; cout << Add(10, 20, 30) << endl; return 0;}
全缺省参数的,几种调用形式
Add()
,没有传递参数,调用函数add是使用三个缺省值。输出流库,定义了标准的输入、
使用C++输入输出更加方便,不需要像printf、
void test(){ cout << "void test()" << endl;}void test(int n = 4){ cout << "void test(int n = 4)" << endl;}int main(){ test(); return 0;}
引用(reference)
引用概念
很牛的东西。C++规定临时对象具有常性(常性,形如被const修饰),这里触发了权限放大,必须使用常引用才可行。
void fun(const int& ra);
inline
使用inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开内联函数,这种调用内联函数的方式就不需要要创建函数栈帧,提高了效率。
Add(10)
,传递了第一个参数,没有后续两个参数,形参b和c使用缺省值。命名空间域,只能定义在全局,它的成员本质上是全局变量。
- namespace关键字后面跟上命名空间的名字,通过大花括号( {} )括在一起,{}中为名称空间的成员,在名称空间内可以对,变量、
在这种情况下,传递NULL想调用int*版本的f函数,但调用的结果时int版本的函数,为了弥补这样的不足,C++引用了关键字nullptr
void f(int x){ cout << "void f(int x)" << endl;}void f(int* x){ cout << "void f(int* x)" << endl;}int main(){ f(1); f(NULL); return 0;}
nullptr在C++11中引用的特殊关键字,nullptr是一种特殊类型的字面常量,它可以转换为其它类型的指针类型。含代码量大,满足这三点其一,都不能称之为内联函数,加上inline后会被编译器忽略。数据类型进行输出,使用流插入运算符(<<)。
解决办法:将返回值进行引用,这里返回的就不会将返回值拷贝在临时对象中,而是给这个返回值取了一个别名,返回的是栈顶元素的别名,对别名加加的结果是栈顶元素大小加1。
使用using展开前,编译器是先查找局部,然后查找全局,有了using将命名空间展开后还会到命名空间内查找,有一种将命名空间成员,改变为全局变量的意味。
命名空间名::变量名
,访问了命名空间域。使用流提取运算符(>>),cin >> 变量名 << endl
,
std::cout
,是ostream类的对象,主要面向窄字符的标准输出流,不需要使用占位符,%d、
int& StackTop(Stack& ps){ assert(ps.top > 0); return ps.arr[ps.top - 1];}int main(){ Stack sk; StackInit(&sk); StackPush(&sk, 1); StackPush(&sk, 2); StackTop(sk)++; return 0;}
无法使用引用进行返回的场景
//指针int* test(){ int ret = 10; //…… return &ret;//返回的是局部变量,函数调用完成后被销毁,返回地址的是一个野指针。
- 函数被编译后是一堆指令需要存储起来执行,内联展开可能会导致可执行程序变大,内存炸开,指令膨胀
- C++设计内联函数的设计目的是为了替代C语言的宏函数,C语言里的宏函数容易出错,需要频繁使用括号,不方便调试。
指定展开命名空间成员
项目中经常使用,且不会存在冲突的名称
#include <iostream>namespace hx{ int n = 10; int num = 20;}using hx::num;int main(){ cout << num << endl; return 0;}
C++的域
C++中域有函数局部域、否则默认使用,其它地方出现的变量/函数/结构体/……
名称空间只能在全局定义,可以嵌套使用
项目工程里,多文件定义同名namespace会认为是同一个namespace,不会发生冲突
C++标准库都放在一个std的命名空间中。调用函数返回后,它的返回值存放在一块临时对象中它具有常性无法被修改。
int main(){ const int a = 0; //编译器报错 error C2440: “初始化”: 无法从“const int”转换为“int &” //int& ra = a;//权限放大 const int& ra = a;//平等关系 int b = 0; int& rc = b; const int& rd = b;//权限缩小 //error C3892: “rd”: 不能给常量赋值 //rd++; rc++; return 0;}
类似于对
int& rb = b * 2; float& d = 3.14; int& rd = d;
。马铃薯,不同的称呼,指向的都是同一个东西。- 内联函数易错点,含有循环语句、%s、对
b * 2
的结果会存放在一个临时变量中,将b * 2的结果计算出来后,编译器放在一个临时对象中,存储中间值。函数、
- 由于这些机制导致了cout的效率不会很高
这三句代码可以提高,C++IO流的效率
int main(){ ios_base::sync_with_stdio(false);//使C语言和C++不同步兼容 cin.tie(nullptr); cout.tie(nullptr);//将cin和cout相互绑定的关系,不会与其它流相互关联 return 0;}
缺省参数
C++中的缺省参数(默认参数),允许在对函数进行声明或定义时为函数参数提供一个缺省值。
局部变量存储在栈上,生命周期时临时的,结束函数的调用或作用域结束时消亡。
- 半缺省参数,部分形参给缺省值,C++规定半缺省值必须从右向左依次给缺省值。
- 使用nullptr就可以避免上述情况出现的问题