当前位置: 首页 > news >正文

C++第一节入门

一、历史

C++是在C上继承拓展的!

java是一家公司(甲骨文)借鉴C++生成的!

C#是微软借鉴java生成的!

二、命名空间

当我们定义一个名叫rand的变量,但是由于stdlib头文件里面有个函数跟rand重名!因此会发生命名冲突!

因此为了解决该问题,C++引入了命名空间的定义!

同一个域里面不可以定义同一个变量!

不同的域里面可以定义同一个变量!(局部变量访问优先)

常见的域有:类域、命名空间域、局部域、全局域

#include<stdio.h>
#include<stdlib.h>int a = 0;
int main()
{int a = 1;printf("%d\n", a);printf("%d\n", ::a);return 0;
}

对于上面这段代码, 打印的第一个a为局部变量;第二个::a为全局变量。

::被称为域作用限定域!

::的左边为空白!(空格无影响),表示的就是在全局域访问!

#include<stdio.h>
#include<stdlib.h>
#include<iostream>int a = 0;
namespace bit
{int a = 1;
}
int main()
{// int a = 2;printf("%d\n", a);   // 打印结果为0//printf("%d\n", ::a);return 0;
}

默认的访问顺序为 局部域->全局域

如果不指定不会访问命名空间域!(默认不会的)

#include<stdio.h>
#include<stdlib.h>
#include<iostream>//int a = 0;
namespace bit
{int a = 1;
}
int main()
{// int a = 2;printf("%d\n", a);//printf("%d\n", ::a);return 0;
}

代码会直接报错!

有两种方法来访问命名空间域:

  • 展开了命名空间域!
  • 指定访问的的命名空间域!

1、展开命名空间域

namespace bit
{int a = 1;
}
// 展开命名空间
using namespace bit;

此时相当于将命令空间中的a暴漏在全局域中!

#include<stdio.h>
#include<stdlib.h>
#include<iostream>int a = 0;
namespace bit
{int a = 1;
}
// 展开命名空间
using namespace bit;int main()
{printf("%d\n", a);return 0;
}

此时会报错,a变量不明确!因为两个变量都位于全局域当中! 

2、指定命名空间

#include<stdio.h>
#include<stdlib.h>
#include<iostream>int a = 0;
namespace bit
{int a = 1;
}
// 展开命名空间
using namespace bit;int main()
{int a = 2;printf("%d\n", a);printf("%d\n", ::a);printf("%d\n", bit::a);return 0;
}

通过作用域限定符指定命名空间,从而访问bit命令空间里面的变量!

展开指的是编译时是否会去命名空间中搜索!

最好不要轻易将命名空间暴漏给全局域!

3、命名空间的定义

  • 正常的命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员。

命名空间中可以定义变量/函数/类型!

namespace bit
{// 命名空间中可以定义变量/函数/类型int rand = 10;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
  • 命令空间可以嵌套
namespace N1
{int a = 0;int b;int Add(int left, int right){return left + right;}namespace N2{int a = 2;int d;int Sub(int left, int right){return left - right;}}
}

此时N1和N2的a为两个不同的变量!

int main()
{printf("%d\n",N1::a);   // 访问N1中的aprintf("%d\n",N1::N2::a);   // 访问N2中的aprintf("%d\n",N1::Add(1,2));return 0;
}
  • 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。

例如有一个quequ.h的头文件定义了如下:

namespace cc
{int x = 0;
}

有一个stack.h的头文件定义了如下:

namespace cc
{int y = 0;
}

此时如果有一个test.c的文件:

#include"stack.h"
#include"queue.h"int main()
{printf("%d\n",cc::x);printf("%d\n",cc::y);return 0;
}

可以访问x和y!(合并到了一个命名空间!)

如何解决同一个命名空间定义变量名相同的变量?

使用命名空间的嵌套!

std标准库

std也被称作C++标准库,包括STL库和C++库

      在C++编程中,using namespace std; 是一条指令,用于告诉编译器在当前作用域中使用标准命名空间(std)。标准命名空间包含了C++标准库中的所有函数、对象和类型,例如cout、cin、vector、string等。 

详细解释

  • 命名空间(namespace):

命名空间是C++中的一种机制,用于防止命名冲突。标准库中所有的名称都被定义在命名空间std中。例如,标准输出流对象cout的完整名称是std::cout。

  • using namespace std;的作用:

当你使用using namespace std;时,你告诉编译器在当前作用域中默认使用std命名空间中的所有名称。这意味着你可以直接使用cout、cin等,而不需要每次都写std::cout、std::cin。

   #include <iostream>using namespace std;int main() {cout << "Hello, World!" << endl;return 0;}

在这个例子中,由于使用了using namespace std;,我们可以直接使用cout和endl,而不需要写成std::cout和std::endl。 

注意事项

  • 命名冲突:

使用using namespace std;可能会导致命名冲突。如果你的代码中包含了与标准库中名称相同的变量或函数名,可能会引发冲突。例如:

   #include <iostream>using namespace std;void sort() {// 自己定义的sort函数}int main() {sort();  // 这是调用自己的sort函数还是标准库的sort函数?return 0;}

在这种情况下,编译器可能会产生混淆,不知道你是要调用标准库中的sort函数还是你自己定义的sort函数。

推荐做法:
为了避免命名冲突,许多开发者更倾向于在需要使用标准库名称时显式地使用std::前缀,特别是在大型项目或库开发中。

   #include <iostream>int main() {std::cout << "Hello, World!" << std::endl;return 0;}

这样可以清楚地知道每个名称的来源,减少命名冲突的风险。

总之,using namespace std; 是一个方便的工具,可以简化代码的书写,但在使用时需要小心,特别是在大型项目中,以避免潜在的命名冲突。

<iostream> 是 C++ 的一个头文件,用于包含输入输出流库。这个库提供了处理输入和输出的功能,例如使用 std::cout 输出到控制台,或使用 std::cin 从控制台读取输入。

总结来说:

  • #include<iostream> 用于引入输入输出功能。
  • using namespace std; 使得可以直接使用 std 命名空间中的标识符,简化代码书写。

将命名空间中某个成员引入

using N::b;
int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0;    
}

可以避免将整个命名空间展开,造成容易出错

总结:命令空间是为了解决C语言的缺陷:即命名冲突!

三、C++输入&输出

std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中!

 <<是流插入运算符,>>是流提取运算符!
cout << "hello world";
  • 相当于把"hello world"流入到显示器当中!
  • cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< 
    iostream >头文件中。
cout << "hello world"<<'\n'<<endl;
  • 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
    C++的输入输出可以自动识别变量类型。

C++控制输出精度和宽度比较复杂!且不容易记住,建议使用C语言的输出形式控制精度!

printf的输出比C++的cout输出快!

  1. 缓冲机制

    • printf 使用的是C标准库的 stdio.h,其输出是基于缓冲区的。默认情况下,标准输出是行缓冲的,这意味着输出会在遇到换行符时刷新。
    • cout 使用的是C++标准库的 iostream,其输出也是基于缓冲区的,但它还涉及到对象和流操作,这可能会增加一些开销。此外,cout 默认是同步与C的标准输出流(printf),这也会影响性能。
  2. 同步机制

    • C++的 iostream 库默认与C标准库的 stdio 同步,以确保混合使用 printf 和 cout 时的输出顺序正确。这种同步机制会带来额外的性能开销。
    • 你可以通过调用 std::ios::sync_with_stdio(false); 来禁用这种同步,从而提高 cout 的性能:
      ​#include <iostream>using namespace std;int main() {ios::sync_with_stdio(false);  // 禁用与stdio的同步cout << "Hello, World!" << endl;return 0;}​
  3. 格式化和类型安全

    • printf 是一个基于格式字符串的函数,它直接操作C风格的字符串,效率较高,但缺乏类型安全和灵活性。
    • cout 是类型安全的,它使用运算符重载来处理不同类型的数据,这虽然带来了更高的灵活性和安全性,但也增加了运行时的开销。
  4. 模板和流操作

    1. cout 使用了模板和流操作,这些都是C++语言特有的高级特性,虽然提供了更强大的功能和更好的类型安全性,但也会引入额外的开销。


http://www.mrgr.cn/news/22520.html

相关文章:

  • JLabel设置字体大小颜色背景色
  • Go语言中实现安全高效的JWT认证:自定义中间件解析
  • nodejs 使用kafka案例,node-red配置kafka案例,从安装配置kafka开始
  • GraalVM的资料
  • 组件拆分综合案例——商城首页
  • 第T6周:好莱坞明星识别
  • 线性因子模型 - 独立分量分析(ICA)篇
  • Go语言现代web开发04 变量常量以及类型转换
  • 机器学习TFIDF的情感分类文章
  • 寻找身高相近的小朋友
  • 数据结构与算法03 顺序表+链表
  • 沁恒CH32在MounRiver Studio上环境配置以及使用详细教程
  • 最大公因数:欧几里得算法
  • goreplay流量重放备忘
  • Linux 文件查找命令which,find详解
  • 使用SSH KEY
  • JavaFx生成树型结构
  • 键盘快捷键:提高工作效率与电脑操作的利器
  • ThreadLocal 释放的方式有哪些
  • 【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)