【C++】理解C++和C的区别

iostream文件

  1. iostream中的io指的是输入(进入程序的信息)和输出(从程序中发送出去的信息)。
  2. c++的输入、输出方案涉及iostream文件中的多个定义。比如用来输出信息的cout就在其中。

头文件名的区别

  • C语言
    C语言的传统是头文件使用扩展名 h,将其作为一种通过名称标识文件类型的简单方式。例如 math.h支持一些数学函数。

  • C++
    C++头文件没有扩展名。
    有些C头文件被转换成C++头文件,这些文件被重新命名,去掉了扩展名h,并在文件名称前面加上前缀c(表示来自C语言)

  • 名称空间namespace
    如果使用的是iostream,而不是iostream.h,则应使用名称空间编译指令来使iostream中的定义对程序可用,即

using namespace std;

有了这句using编译指令,才能使用cout、cin等,或者用第二种方式:

using std::cout;
using std::cin;
using std::endl;

封装性:

创建一个头文件 aa.h
里面编写 :

#pragma once
namespace aa
{
	typedef int INT;
	typename char CHAR;
};

然后在cpp文件中引入该头文件,但我们却无法使用之前写好的东西。
#include "aa.h" //无法引用 INT a = 10;
INT a会报错,因为我们只引入了头文件,没有使用里面的名称空间。
需要再加入:
using namespace AA;或者using AA::INT;

指针和数组名的区别

(指针是变量,数组名是一个地址常量)

#include<iostream

using namespace std;

int main(void)
{
	int a = 10;
	int* p = &a;
	int arr[] = { 0,1,2,3,4 };

//这里定义了一个指针p和一个数组arr。
	cout << p << endl;
	cout << arr << endl;
//运行结果都是地址
	return 0;
}

输出
请添加图片描述
反汇编:
请添加图片描述

请添加图片描述

cout << p << endl;
请添加图片描述
cout << arr << endl;
请添加图片描述
1. 在输出指针时,需要先从p里面取出四字节,再放到寄存器里push;
2.在输出arr时,直接把arr放到寄存器里再push。

解引用


指针的解引用的值是变量的地址:
原理:

	int a = 10;
008F1B02  mov         dword ptr [a],0Ah  //10 赋值给a
	int* p = &a;                          
008F1B09  lea         eax,[a]             //a的地址放入寄存器
008F1B0C  mov         dword ptr [p],eax     //p中的四个字节 存放a的地址
	*p = 20;
008F1B0F  mov         eax,dword ptr [p]     
008F1B12  mov         dword ptr [eax],14h    //20给寄存器,完成对a的改变

1.解引用,就是把值从地址中取出来。

int main(void)
{
	int a = 10, b = 20;
	int* p = &a;
	
	b = *p;

	return 0;
}
	int a = 10, b = 20;
00F81B02  mov         dword ptr [a],0Ah  
00F81B09  mov         dword ptr [b],14h  
	int* p = &a;
00F81B10  lea         eax,[a]                  a的地址 放入eax
00F81B13  mov         dword ptr [p],eax        p取四字节存入eax中的四字节
	
	b = *p;
00F81B16  mov         eax,dword ptr [p]      p里取四字节放入寄存器
00F81B19  mov         ecx,dword ptr [eax]   从eax取出四字节放入ecx
00F81B1B  mov         dword ptr [b],ecx     再从ecx中内容给变量b的四字节

2.解引用就是从地址中取值。
b = *p,可以看出,用一个变量往另外一个变量中赋值,也是解引用

int a = 10;
00F80FD8  mov         dword ptr [a],0Ah  
	int b;
	b = a;
00F80FDF  mov         eax,dword ptr [a]  
00F80FE2  mov         dword ptr [b],eax  

可以得出: 解引用就是去地址中取值。

C语言和C++中const的区别:

int main()
{
 const int a = 10;
 int b = 20;  //常量赋值
 b =a;  //常变量赋值
}
const int a = 10;
00311825  mov         dword ptr [a],0Ah   
	int b = 20;
0031182C  mov         dword ptr [b],14h  //20直接给b

	b = a;
00311833  mov         eax,dword ptr [a]   先将a的值放入寄存器, 
00311836  mov         dword ptr [b],eax    b再从寄存器中取值
#include<stdio.h>

int main(void)
{
	const int a = 10;
	int b;
	b = a;
	int* p = &a;  //指针可以改变 a的值,而c++中不行
	*p = 100;
	return 0;
}

指针可以改变 a的值,而c++中不行
请添加图片描述


在C++中,const修饰的变量就是常量,和常量一模一样
编译阶段会直接将常量的值替换掉常量的使用点。
C语言反汇编:

int main(void)
{
	const int a = 10;

	int b, c;

	b = 16;
	c = a;

	return 0;
}
const int a = 10;
00101828  mov         dword ptr [a],0Ah  

	int b, c;

	b = 16;
0010182F  mov         dword ptr [b],10h  
	c = a;
00101836  mov         eax,dword ptr [a]    //在c语言中a还是变量
00101839  mov         dword ptr [c],eax  

c++反汇编

const int a = 10;
003E1828  mov         dword ptr [a],0Ah  

	int b, c;

	b = 16;
003E182F  mov         dword ptr [b],10h  
	c = a;
003E1836  mov         dword ptr [c],0Ah    //在C++中a已经被替换成常量

1.const修饰的变量,必须初始化,因为在编译阶段,会被替换成常量,如果不初始化,后面将没有机会对其赋值
2.如果变量对const修饰的变量赋值,则回退化成常变量。

C语言面向过程的语言
效率高,不需要实例化
如洗衣服: 放衣服–>加洗衣粉–>加水—>漂洗---->清洗----->甩干
C++面向对象的语言
:易扩展。易维护,有封装,继承,和多态的特点。可以设计出高内聚和低耦合的系统
new 出一个人和洗衣机:
”人“ 加入属性和方法:放衣服(方法)、加洗衣粉(方法)、加水(方法)
”洗衣机“ 加入属性和方法:漂洗(方法)、清洗(方法)、甩干(方法)
然后执行:
人.放衣服(方法)-> 人.加洗衣粉(方法)-> 人.加水(方法)-> 洗衣机.漂洗(方法)-> 洗衣机.清洗(方法)-> 洗衣机.甩干(方法)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C、传统 C++ #include <assert.h>    //设定插入点 #include <ctype.h>     //字符处理 #include <errno.h>     //定义错误码 #include <float.h>     //浮点数处理 #include <fstream.h>    //文件输入/输出 #include <iomanip.h>    //参数化输入/输出 #include <iostream.h>   //数据流输入/输出 #include <limits.h>    //定义各种数据类型最值常量 #include <locale.h>    //定义本地化函数 #include <math.h>     //定义数学函数 #include <stdio.h>     //定义输入/输出函数 #include <stdlib.h>    //定义杂项函数及内存分配函数 #include <string.h>    //字符串处理 #include <strstrea.h>   //基于数组的输入/输出 #include <time.h>     //定义关于时间的函数 #include <wchar.h>     //宽字符处理及输入/输出 #include <wctype.h>    //宽字符分类 ////////////////////////////////////////////////////////////////////////// 标准 C++ (同上的不再注释) #include <algorithm>    //STL 通用算法 #include <bitset>     //STL 位集容器 #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex>     //复数类 #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque>      //STL 双端队列容器 #include <exception>    //异常处理类 #include <fstream> #include <functional>   //STL 定义运算函数(代替运算符) #include <limits> #include <list>      //STL 线性列表容器 #include <map>       //STL 映射容器 #include <iomanip> #include <ios>       //基本输入/输出支持 #include <iosfwd>     //输入/输出系统使用的前置声明 #include <iostream> #include <istream>     //基本输入流 #include <ostream>     //基本输出流 #include <queue>      //STL 队列容器 #include <set>       //STL 集合容器 #include <sstream>     //基于字符串的流 #include <stack>      //STL 堆栈容器     #include <stdexcept>    //标准异常类 #include <streambuf>    //底层输入/输出支持 #include <string>     //字符串类 #include <utility>     //STL 通用模板类 #include <vector>     //STL 动态数组容器 #include <cwchar> #include <cwctype> using namespace std; ////////////////////////////////////////////////////////////////////////// C99 增加 #include <complex.h>   //复数处理 #include <fenv.h>    //浮点环境 #include <inttypes.h>  //整数格式转换 #include <stdbool.h>   //布尔环境 #include <stdint.h>   //整型环境 #include <tgmath.h>   //通用类型数学宏 --------------------------------------------------------------------------------------------------------- 补充: 经常在CSDN以及其他之类的技术论坛上问关于C++ 头文件的问题。提出这些问题的往往就是那些刚学C++的新手。当初我是菜鸟的时候也问过类似的问题。 现在来看看下面两个include: #include<iostream> // 这个就是1998年标准化以后的标准头文件 #include<iostream.h> // 这个就是标准化以前的头文件 更本质上的区别就是iostream把标准C++库的组件放在一个名位std的namespace里面。而相对的iostream.h则将这些标准组件放在全局空间里,同时在标准化以后旧有的C标准库也已经经过改造了。 看看下面这两个头文件 // 标准化后经过改造的C的标准库,所有的组件都放在了std中 #include<cstdio> // 标准化以前C++中的C标准库 #include<stdio.h> // 在看看这个头文件C标准库下 基于char* 的字符处理函数库 #include<string.h> // 在标准化以后他变成了这样 #include<cstring> // 但是很多朋友还看见过这个字符串处理函数库,他包含了新的string class #include<string> 经过了标准委员会如此大规模手术后,在98年以前出品的C++编译器(BC3.0,BC5.0)上能顺利通过编译的源文件,在支持新标准的编译器上可能无法顺利通过编译也就是很正常的事了。 [起因] 在回过头来看看标准程序库,这个程序库涵盖范围相当广大,提过了许许多多好用的功能。正是因为这样标准程序库中class的名称和函数名与第三方提供的程序库中的class名或是函数名发生名字冲突的可能性大大增大。为了避免这个问题的发生,标准委员会决定将标准程序库中每一样东西都放在namespace std中。但是这么做同时有引来了一个新的问题。很多C++程序代码依赖那些已经存在很多年的C++ “准”标准程序库(C++迟迟未标准化才导致这些情况的发生),例如iosteam.h,complex.h等等。 为了解决这个新出现的问题,标准化委员会决定设计一些新的头文件名,给那些穿上std外衣的组件所使用。把C++头文件的.h去掉,于是就有前面出现的iostream,同样C的头文件也做了相同的处理,同时在前面加上了一个字母c,以表示是C的头文件(感觉上有中种族歧视的感觉)。同时标准化委员会声明就有的C++头文件将不再列于被支持的名单之中了,而旧有的C头文件为了满足“对C的兼容性”这个古老契约,仍然将继续存活下去。 但是,那些编译器厂商不可能去推翻他们客户的旧有编译器(也跟本不会去这么做),所以那些旧有的C++头文件仍然苟延残喘的活了下来,并不断的扰乱那些C++新兵的心智。 下面就是现在大多数C++开发工具表示头文件的组织状态: 1. 旧的C++头文件 比如iostream.h,他们虽然被标准化委员会所抛弃,但由于各大厂商为了各自的商业利益仍然将继续存活下去,这些头文件的内容将不处于namespace std中。 2. 新的C++头文件如iostream虽然提供了和旧有头文件相同的功能,但他的内容都并入了namespace std中,从而有效避免了名字污染的问题。 3. 标准C的头文件如stdio.h继续获得支持,这类文件的内容并未放在std中。 4. C函数库的技能也有对应的新式C++版本,起名称类似cstdio,这类头文件的内容也有幸穿上了std的外衣。 其实标准化以后的标准程序库的改动并不只有这些而已,很多的标准化组件都被“tamplate化”。其中就有元老级人物iostream。标准程序库的问题并不是用一篇,两篇文章就可以说清楚的。如果你像进一步的了解C++的标准程序库的话,你可以看看侯先生的《C++标准程序库》。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值