C++适合本地程序的开发.Go语言适合网络程序和本地程序的开发.Go的优点:垃圾回收,语意明确,格式统一.?Go的缺点:效率目前没有C++高,但对于桌面程序而言,效率问题不大,因为硬件已经很快了.c++过于复杂了,加入很多炫技的内容.这些内容脱离了事情的本质.
最明显的就是所谓的面向对象.基于面向对象的工程如果足够大的情况下,会带来很大的耦合度,如果再加上内存管理,多线程等等.项目后期基本上没办法维护和增加功能.
关于c++的语言复杂性,你可以问知乎上的任何一位高手.没一个敢说自己精通c++.你也可以去看一下所有的c++编绎器,没有任何一个敢说自己完全实现了c++的标准.不同的编绎器之间实现细节又不同.所以功能再强大没有实用性,就失去了意义,只会制造更多的问题.
大家都知道我们可以使用C语言写一段程序来控制硬件工作,但你知道其工作原理吗?以下仅供参考!
c语言在实际运行中,都是以汇编指令的方式运行的,由编译器把C语言编译成汇编指令,CPU直接执行汇编指令.
所以这个问题就变成,汇编指令是如何操作硬件的?
方式一:
通过向内存空间写数据.硬件会把硬件上的各种寄存器(外行可以理解为访问硬件的接口或者操作硬件的工具)映射到某一块内存地址空间上,之后只要用汇编指令,甚至C语言去读写这一段内存地址空间(并非真正操作物理内存),就可以达到操作硬件的目的了.
如果题主还有WindowsXP环境(虚拟机也可以),就可以用汇编指令直接操作显存:
MOV ES,AX
XOR DI,DI
REPZ STOSB
硬件的各种寄存器会被映射到某一块物理内存中,这种方式称为MMIO,在Windows的设备管理器里,右键点设备,看属性->>资源里,不少硬件设备都有"内存范围"的参数,这里的内存范围就表示这个硬件的资源可以通过访问这一段内存来控制它.
方式二:
以上两种访问硬件的方式,第一种是可以用C语言实现的,上面一段汇编,本质上类似于C语言代码:
int i;
}
第二种IN/OUT方式没有直接的C语言语法对应,需要自己封装汇编.
那么为什么平时很难用C语言操作硬件呢?这是因为平时写的代码大多数都在保护模式下,保护模式下,直接访问物理地址会受到限制,C语言操作的地址都是虚地址.
对于Windows来说,要访问物理地址,需要工作在内核模式,也就是的写驱动才行.
而在显存方面,首先,题主要先明白物理地址和虚拟地址的概念.
可见这一段内存至今仍然是留给显卡使用的.
那么现在为什么不能直接用这段内存了?
如果要想用这段显存怎么办?
显卡那么多显存是怎么映射的?
有很多内存地址被映射给显存了,就是通过这种映射关系,把一些物理地址留给显存,使得CPU能像访问内存一样访问显存资源.
还有一个很有意思的事情:在虚拟机里,找到映射的高地址部分的第一块内存区域,写一个能直接访问物理地址的程序(比如一个驱动),去读这一块内存,然后写到文件里,再用屏幕截图,也写到文件里,会发现截图的内容和显存里读出来的内容基本上是一样的.
网友awayisblue
要回答你的问题,我们需要要知道:
硬件是一种什么样的存在
什么是驱动.
C语言怎么操作硬件
我就不严格去定义这些概念了,我就以一个例子来通俗地讲解一下吧.
首先讲硬件:
这款芯片里面有cpu, 内存,寄存器(先不要觉得看到新名词压力大,继续往下看)等等,相当于我们的电脑了,但还要外接其它硬件.
这里你需要知道的概念是:
cpu可以执行代码指令,指令可以操作内存.
结论:所以从上面两点可以我们可以知道,cpu可以执行指令,使芯片的引脚电平(电压)发生变化.
关于这款显示器,我们需要知道的是:
它是有引脚的,这些引脚可以跟到前面介绍的那款单片机芯片的引脚相连.
该显示器有自带的内存,用于存储要显示的字符,显示器从该内存里面读取字符来来显示.
单片机芯片与该显示器相连后,可以通过引脚往该显示器的内存里写数据(通过多个引脚电平的高低不同来代表不同的数据,比如说:低高高低低低低高 代表01100001,这个数据写在显示器的.内存里面,被显示器所显示,当然,会根据ASCII来显示数字对应的字符,01100001对应的字符是'a'),除了接收数据的引脚外,还有控制显示器的引脚(这个我们会在驱动那里介绍,继续往下看).
结论:单片机芯片与显示器相连,可以通过引脚输出的电平来控制显示器的字符显示.
那么,综合上面,也就是说,单片机芯片cpu可以通过执行指令来控制显示器的字符显示.
而这里,题主所说的硬件,指的就是这个显示器了.
此时此刻呢讲驱动:
那么,什么是驱动呢?驱动无非就是硬件跟软件的中间层,但我们不纠结这种关系,直接来看一下,对于我们这个例子,驱动指的是什么.首先我们要知道:
显示器支持很多种操作,比如说清除显示,光标移动,读取数据,写数据等等.
这些操作数据引脚和控制引脚来实现.
引脚可以通过单片机芯片来控制.
结论:我们可以通过在单片机芯片里面写显示器的"驱动"程序来屏蔽掉硬件(显示器硬件)层.
于是这里驱动程序,指的是显示器所支持操作的程序表示.比如说清除显示,我们可以编写一个clear()函数,光标移动,我们编写一个move_cursor()函数,读取数据和写数据分别为read()和write(),然后分别实现就可以了(通过向寄存器里写数据的形式,进而控制引脚的电平变化,再而控制显示器,这个过程前面已有介绍).这些函数就是驱动程序了.为什么上面说驱动程序可以屏蔽掉硬件呢?因为程序员可以使用前面的驱动程序来直接操作显示器(硬件),而不用知道太多关于硬件的事情,而一般的驱动程序也可以由厂家来提供.
再说明一点:一般这些驱动程序可以用汇编写(出于运行效率的考虑),也可以用C语言来编写的,比如说我上面的例子,就可以直接用C语言来编写.当然C语言内联汇编的形式也可以.
最后讲C语言怎么操作硬件:
相信到这里,C语言是怎么操作硬件的已经比较明白了.
这里最后提醒一下大家:
C语言由CPU运行(实际上是先编译成机器码存在芯片里面然后执行),可以去操作内存.
内存里有一段是跟寄存器相对应的,而寄存器是跟芯片的引脚相对应的,于是操作该段内存就能控制芯片引脚的电压变化.
硬件(比如说显示器)有引脚(或者说排线,这些也是一样的东西),这些引脚跟芯片的引脚相连可以接受芯片的控制.
可以把对某个硬件的操作做成一系列操作函数,这些操作函数就是驱动程序了.
于是我们的C语言只要去调用这个驱动程序就可以直接操作硬件了.(当然驱动程序也可以由C语言来编写,所以C语言操作硬件并不一定要经过驱动程序).
你需要理清一个根本概念,语言本身是为了人与机器交互而产生的,所有语言最终生成的都是让硬件工作的"机器码".从这个角度来说,你的每一条C语句本身就已经是在给"硬件编程序"了.
硬件并不关心,也不知道你的编程语言到底是什么.之所以在单片机、DSP等硬件设计领域C语言的使用率最高,一方面是因为C语言是它那个年代所出现的最优秀的面向结构语言,所以呢被习惯性地采用,各大厂商开发出了众多的面向具体芯片的C编译器(把C语言转换成相应芯片的机器码),一直延续到了今天;二是因为芯片面向的是底层应用,具体化程度高,抽象性低,采用面向对象语言的总体意义不大,所以目前还没有被面向对象语言代替的趋势(但是并非没有这方面的发展,比如谷歌的Go语言).不过我相信随着IoT的迅速发展,嵌入式系统的语言和相应的编译器会很快发生巨大的变化.
希望能对你有所帮助.