☺初识c++(语法篇)☺

简介: ☺初识c++(语法篇)☺

一·命名空间(namespace):
namespace ns {
int t = 5;
}//习惯写法:namespace+名字,注:末尾无;
这里相当于命名空间域;访问的时候要ns::+内部的量

对于c++域的理解:可分为四大域:函数局部域,全局域,命名空间域,类域。

其中前两个影响编译逻辑和生命周期,后两者不影响。

对于命名空间特点:

首先它是可以嵌套的:

namespace ns {
int i = 10;
int a = 10;
namespace ne {
int a = 2;//命名空间的嵌套

}

}
这时如果访问ne内的a:可以ns::ne::a;或者可以不完全展开即 using namespace ns::ne。

还有一个就是多文件定义同一个命名空间它会自动合并如:

在头文件中定义一个ns命名空间,在cpp中也存在ns命名空间,同时在cpp调用就可以用到头文件中的ns。

对于standard 命名空间,在iostream库里存在的cin cout 就定义在std这个命名空间里。

二·cout与cin简述:
cin输入的数据自动识别为字符型,cout输出也是类同。

前者配合>>后者配合<<,由于是二元操作符,故只能是两个操作数即里面要么是变量自动识别,要么是字符串。

结合endl(end line ):都是存在于iostream库中的namespace std,故可以对它展开或者std::来使用。

int k= 10;
int e = 0;
int main() {

std::cout << "k是" << k<< endl;
std::cin >> e >> k;
std::cout << "k是" << k << endl;
std::cout << "e是" << e << endl;

}
为了提高io效率,可以在程序中加入:

ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
三·缺省参数:
顾名思义,就是对于函数有的参数没有的时候可以去固定值,也可以输入:

大致就是要从函数所有参数的右边开始缺省,到左边,但是不能跳跃,当传参的时候省略的可传可不传。

using namespace std;
namespace hs {
int Func(int a, int b, int c = 10) {
return a + b + c;
}

}

if 0

int main() {
cout << hs::Func(1, 2) << endl;

}

endif

这里由于为给传参,故用默认的即输出13。

四·函数重载:

即重载在同一作用域下,参数个数不同或者类型不同而函数名相同可以构成重载。通过调用函数的时候传参个数或者类型来取决调用哪个函数。

如:

using namespace std;
namespace hs {
int Func(int a, int b, int c = 10) {
return a + b + c;
}
double Func(double a, int b, int c = 11) {
return a + b + c;
}
}

if 0

int main() {
cout << hs::Func(1.1, 2) << endl;

}

endif

这里调用的就是double类型的Func。(参数类型不同)

using namespace std;
namespace hs {
int Func(int a, int b) {
return a + b ;
}
int Func(int a, int b, int c = 11) {
return a + b + c;
}
}

if 0

int main() {
cout << hs::Func(1, 2) << endl;

}

endif

这里调用的就是第一个Func。(参数个数不同),当然,也可以是参数顺序不同等等。

而函数重载是为了能调用的时候根据输入区分开不同的函数,故当只有返回值不同时不能作为重载条件:

void fxx()
{}

int fxx()
{
return 0;
}
上面这样当调用的时候编译器无法区分。

void f1 ()
{
cout << "f()" << endl;
}
void f1 ( int a = 10)
{
cout << "f(int a)" << endl;
}//由于参数是不同的,可以构成重载,但是调用的时候如果不输入,编译器无法区分调哪一个。
五·引用:
即类型&引⽤别名=引⽤对象

相当于给它取了一个新的名字,但还是同一块内存区域,即地址不变,可以理解为改变的时候类似于指针操作。

因此就可以换一种方式交换两个数:

namespace yy {
int c = 10;
int& b = c;
namespace jh {
int m = 1;
int n = 2;
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
}

}
using namespace yy::jh;

if 0

int main() {
cin >> yy::c;
cout << &yy::b <<'\n'<< & yy::c << endl;
cout << m <<" "<< n << endl;
swap(m, n);
cout << m << " " << n << endl;
}

endif

这里通过这个引用把m n的值交换了,但m n这块地址没有变,通过m n找到对应的地址把里面的数据改变。(因为a,b是m n的别名故改变a b即改变m n) 。

这里注意一旦引用实体,不能再引用其他:

int main() {
int a = 10;
int& b = a;
int d = 11;
b = d;
cout << "b" <<&b<<" "<<"a" << &a << " " << "d" << &d << endl;
return 0;
}

这里可以看出,a b还是同一块地址,b指向的地址里数据只是对d数据的一次拷贝,而不是让b这个实体再次引用d。

const引用:对于权限引用:范围可以缩小,可以等同,但不能放大:

即:

const int a=10;
const int &b=a;//等同

int c=10;
const int& d=c;//缩小
这里虽然地址是同一个,但访问权限不同。

再看着一个例子:

const int a=10;
int d=a;//这里并非扩大访问,只是把a值copy给d,两者地址不同
下面引出临对象:所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象。

而当在c++中经常会出现,那么把它就要当成常性对待,不可修改故用const修饰。

int a=10;
int b=1;
const int &c=(a+b);
//这里a+b就是临时对象
再比如隐式类型转化出现的临时对象:

double d = 3.14;
int i = d;
const int& ra = d;
cout << i << " " << ra << endl;

六·内联函数:
即用inline修饰的函数,设计出来代替宏:

而宏:采用直接替换,不开辟空间,但效率慢。

普通函数:开辟多余空间,即建立栈帧,效率高。

而内联函数结合了这两点:

即当使用内联函数,如果遇到短小函数,不复杂的则编译器按照宏的方式去直接替换;但是遇到比如有递归等,就会按照函数方式直接展开建立栈帧去执行如:

namespace nl{

inline int add(int& a, int &b) {
    return a + b;
}
inline int Add(int a, int b) {
    if (a + b > 10) {
        return a + b;
    }
    return Add(a+3,b+3)+1;
}

}
int main() {
int m = 1, n = 2;
cout << nl::add(m, n) << endl;
//这里由于短小函数,故采用类似宏的直接替换。
cout << nl::Add(m, n) << endl;
//这里由于出现了递归故采用直接展开即开辟一定空间。
return 0;
}

再如c++库里面swap函数就用的inline修饰的内联函数;

适用范围:频繁调用的短小函数(非递归)。

七·c++中的nullptr简述:
C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换 成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被 隐式地转换为指针类型,⽽不能被转换为整数类型。类似c中的NULL。

void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int ptr)
{
cout << "f(int
ptr)" << endl;
}

int main() {
f(0);
f(NULL);
f(nullptr);
return 0;

}

这里对于c语言可能NULL可以这样,但是c++会直接识别为0;故在这里c++对空指针用nullptr。

相关文章
|
6月前
|
Java C# C++
C++ 11新特性之语法甜点1
C++ 11新特性之语法甜点1
51 4
|
6月前
|
编译器 C++ 容器
C++ 11新特性之语法甜点2
C++ 11新特性之语法甜点2
53 1
|
6月前
|
存储 算法 编译器
C++ 11新特性之语法甜点4
C++ 11新特性之语法甜点4
49 0
|
6月前
|
安全 C++ 容器
C++ 11新特性之语法甜点3
C++ 11新特性之语法甜点3
56 0
|
7月前
|
编译器 C++ 容器
C++语言的基本语法
想掌握一门编程语言,第一步就是需要熟悉基本的环境,然后就是最重要的语法知识。 C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 - 摇动、叫唤、吃。对象是类的实例。 类 - 类可以定义为描述对象行为/状态的模板/蓝图。 方法 - 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。 即时变量 - 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。 完整关键字
141 2
|
8月前
|
Java 编译器 程序员
C++中的语法知识虚继承和虚基类
**C++中的多继承可能导致命名冲突和数据冗余,尤其在菱形继承中。为解决这一问题,C++引入了虚继承(virtual inheritance),确保派生类只保留虚基类的一份实例,消除二义性。虚继承通过`virtual`关键字指定,允许明确访问特定路径上的成员,如`B::m_a`或`C::m_a`。这样,即使基类在继承链中多次出现,也只有一份成员副本,简化了内存布局并避免冲突。虚继承应在需要时提前在继承声明中指定,影响到从虚基类派生的所有后代类。**
109 7
|
8月前
|
编译器 C++ 开发者
C++一分钟之-属性(attributes)与属性语法
【7月更文挑战第3天】C++的属性(attributes)自C++11起允许附加编译器指令,如`[[nodiscard]]`和`[[maybe_unused]]`,影响优化和警告。注意属性放置、兼容性和适度使用,以确保代码清晰和可移植。示例展示了如何使用属性来提示编译器处理返回值和未使用变量,以及利用编译器扩展进行自动清理。属性是提升代码质量的工具,但应谨慎使用。
230 13
|
9月前
|
编译器 程序员 C++
C++一分钟之-属性(attributed)与属性语法
【6月更文挑战第28天】C++的属性为代码添加元数据,帮助编译器理解意图。C++11引入属性语法`[[attribute]]`,但支持取决于编译器。常见属性如`nodiscard`提示检查返回值,`maybe_unused`防止未使用警告。问题包括兼容性、过度依赖和误用。使用属性时需谨慎,确保团队共识,适时更新以适应C++新特性。通过示例展示了`nodiscard`和`likely/unlikely`的用法,强调正确使用属性能提升代码质量和性能。
170 13
|
9月前
|
编译器 C语言 C++
|
9月前
|
C++
C++的引用定义语法和应用
C++的引用定义语法和应用