先打个广告欢迎加入编程<->逆向群: 90569473 ,本群无任何不良目的,欢迎加入!
前言
当走遍整个大学城附近的所有书店而找不到一本《四书五经》时,我终于明白,中国人不是没有思想,只是没有善于学习及利用,而面对中国的教育,却把几千年中国古典文化中的好的、坏的都抛之脑后,这无疑不利于我们民族的发展。
作为一个平凡的人,我不求有功,但求能为此而作出一点努力,同时也愿意为自己的言论承受各种荣辱,正所谓不能忍辱岂能负重,希望通过本文唤起一种用中国古典哲学探索事物、学习知识的浪潮!
目录:
1:C++编程语言是什么?
1.1:C++编程语言简介
1.2:人机合一与字符串
2:C++作为编程语言需要解决的问题
2.1:信息如何存储
2.2:信息如何处理
3:编写一个C++入门程序
3.1:编写并执行程序
3.2:编码源码阶断
3.3:预处理阶断
3.4:编译阶断
3.5:汇编阶断
3.6:链接阶断
4:阴阳学说与C++
4.1:阴阳学说与C++编程思想
4.2:阴阳关系与二进制
第一章:C++概述
C++是一种编程语言,在人类社会里,基本上每一种事物都有一个名字,即使不认识的事物也被称为未知事物,所以名字往往里包含了这个事物被人们使用的最大特性!
一:C++编程语言是什么?
1.1:C++编程语言
“C++编程语言”的名字告诉我们其一有一种编程语言叫C++,其二C++是一种编程语言,对于其一来说,作为编程编程语言C++为什么称为C++而不叫++C,这源于C++运算符中的增量运算符,前++与后++有着本质的不同,前++先将操作数增1再进行运算,而后++则先将操作进行运算,然后再增加1,用C++命名正是告诉人们,C++保存了C语言的基本内容,而后“加1”,这个加1主要是指加入了面向对象程序设计部分;对于其二来说,C++是一种语言,不管世界上人类发明的哪一种语言都有基本的元素组成,比如英语是在26个字母的基础上排列组合得到的,再比如汉语是在横、竖、撇、捺、折、勾基础上排列组合组成的,与举出的例子相同,C++也有基本的组成元素,这些元素基本包括了键盘上我们所能看到的可以输入的符号,简单的可以分为如下三种:
1:52个英文大小写
C++的基本元素包括了52个英文大小写,52个而不是26个即代表C++是一种对大小写敏感的数据。如下面的定义语句!
int Int=1;//这是正确的变量定义
int是一个关键字,但是Int就可以作为一个变量名标识符,它代表一片内存区域! 52个英文大小写的主要作用是用于形成标识符、关键字等内容。
标识符:在C++源码中起标识内存区域作用的符号,如上面的Int就是一个标识符,它表示一块内存!C++中每一个标识符的第一个符号只能是“_”或字母,每一个标识符都有数字、字母及“_”组成!
关键字:在C++源码中起关键作用的字符,如上面的int就是一个关键字,它的主要用于编译器进行词法分析,就像本书中看到的文字一样,每一个逗号都可以理解为一个关键字,当你读到逗号的时候,你会自然知道是一句没有说完的话,而此时你的大脑正在进行“词法分析”!
2:特殊符号
C++中的特殊符号主要用作运算符的表示,所以在标识符中,只能使用一种特殊符号“_”(下划线),因为只有这一个特殊符号不用作运算符!
3:数字
现代计算机系统遵循冯诺伊曼的“存储程序”原理,“存储程序”原理的核心思想有两条,第一条是所有信息用二进制进行编码,第二条是计算机系统有输入\输出系统、CPU、存储器等部件组成,计算机中的程序遵循先存储,后执行的流程!
因此数字是C++不可不用的基本语言元素!数字在C++中更多的用于数据的描述!
1.2:“人机合一”与字符串
上面C++的三种基本元素的任意组合都可以作为字符串使用,字符串的根本作用是实现人机交互,我们平时所说的普通话、英语等语言,只有一个目的与人们进行交流,而C++编程语言的作用也只有一个与机器交流!
结合“存储程序”原理的核心思想,我觉得“人机合一”的模型更适合一个程序爱好者,即把计算机输出的信息作为人脑的输入信息,把人脑的输出信息当作计算机输入的信息!CPU处理人输入的信息,人脑处理计算机输出的信息!
“人机合一”的过程中,对于机器来说需要输出人能所看懂的信息即字符串,作为人来说要输入计算机所能看懂的信息即机器语言,这就需要一个接口,即能将人类的语言转换成机器能识别的,又能将机器语言转换为人类能识别的,这个接口,我们称为C++I/O系统!
二:C++作为编程语言需要解决的问题
相信很多朋友和我有过的感受一样C++怎么有如此琐碎的知识呢?因此有必要对C++作为编程语言需要解决的问题进行讨论,知道了这个问题即能整体上把握C++!
C++作为编程语言实际上只解决了两个问题信息如何存储及信息如何处理!
2.1:信息如何存储
如下图所示是一个计算机系统的简单层次结构:
在这个图中,上面一个个的圈表示计算机系统的不同层次结构,从最里面的硬件系统,到最外面的应用软件,惟一关联的纽带是程序,程序的主要作用是处理信息!计算机系统中的任何程序都必须遵循“存储程序”原理,所以C++作为编程语言来说必须首先解决的问题是如何存储信息!
为了解决如何存储信息的问题,同其它编程语言一样,C++引入了变量的概念,在C++中定义变量的语法为:
<存储类><数据类型><变量名>=<初值表达式>,<变量名1>=<初值表达式>;
这样的语法结构组成了C++的基本内容,即包括存储类、数据类型、变量、常量等概念!
2.2:如何处理信息
计算机的主要功能是进行数据处理,而这个功能对于编程语言来说,则需要实现数据处理能力,C++提供了三种层次的信息处理方法:
1:运算符
运算符是最基本的信息处理方法,根据“存储程序”原理,计算机中的所有数据都通过二进制进行编码,所以计算机中的信息实际上就是大量的二进制bit流,这是一种数字,数字与数字最基本的关系就是运算,比如加减乘除等!
2:基本控制结构
“信息运算符信息”,如你所见,运算符实现了如何处理信息,运算符与信息相结合的式子,我们称为表达式,根据表达式的执行结果,程序可以产生不同的分支,这些分支在C++中通过基本控制结构来完成!
3:编程思想
编程思想是最高级的信息处理方法,它主要解决了“人脑如何编程”的问题,在C++中提供了两种编程思想结构化程序设计和面向对象程序设计。在下面我们会结合中国古典哲学思想,详细讨论这两种编程思想!
总上所述,C++要解决的问题只有两个信息如何存储及信息如何处理,通过这两个问题不难发现C++最核心的问题是数据类型与编程思想!
三:编写一个C++入门程序
3.1:编写并执行C++程序
输入如下源码:
//1.1.cpp
#include <iostream>
using namespace std;
int main()
{
cout<<"hello world!"<<endl;
return 0;
}
3.2:编写源码阶断
1.1.cpp是一个标准的C++程序,下面对其每句进行解释:
#include <iostream>,此句为一个预处理语句,预处理以#号开头,一句一行,include的作用是将其后的iostream文件中的内容直接添加到这里!
using namespace std;此句为使用全局名字空间std,所谓名字空间是为了防止用户编码源码时,声明一些与函数库相同的变量而导致程序出现错误而引入的,比如,张三这个人,在中国有很多叫张三的人,如果加上中国北京海淀区狗不拉屎街1号的张三就能很容易找到这个人了,前面的地址就相当于名字空间std!
int main()此句标识一个主函数,任何一个C++程序都有一个主函数,程序执行流程通过主函数进入,int表示该函数的返回类型!
cout<<"hello world!"<<endl;:此句是将“hello world!”字符串输出到标准输出(屏幕)中,以“;”结束表示是一条语句,C++中的语句以分号“;”结束!
{}:多条语句需要用{}括起来,表示一个语句块!
return 0;:表示程序执行完成后的返回值,0表示成功执行完毕!
C++程序的源码文件一般为.cpp!当我们单击“组建”后,所有的工作用编译器和链接器完成,具体的过程如下:
3.3:预处理阶断
首先编译器进入预处理阶断,这个过程会处理以#开头的预处理语句,在示例中会将include目录下的iostream文件的内容直接复制到当前位置!
为了后面我们能方便的使用OD处理程序,在Vc++环境中,单击“文件”“新建”“C/C++ Header File”,在文件名处输入“head.h”,添加一个head.h的头文件!然后输入如下预处理内容:
#ifdef FAST
#pragma comment(linker,"/entry:main")
#endif
它的作用是当定义FAST宏后,程序会直接定位到main函数处的代码,方便以后使用OD调试!保存后退出,在工程区,选定“1.1 files”,右键选择“添加文件到工程”,选择我们刚才建立的head.h,在“文件”中选择“保存工作空间”!
最后将1.1.cpp中的#include <iostream>和using namespace std;剪切到head.h中,在1.1.cpp中加入一条预处理指令:
#include "head.h"
到这里就建立好了我们的学习开发环境!
3.4:编译阶断
在这个阶断中编译器需要将我们输入的C++源码转换成汇编指令,因为开发一个编译器的难度是很大的,而最好的方法是利用已有的编译器,于是C++借用了汇编编译器,正因为此,所以每一个C++程序首先需要先通过编译器转换成汇编指令!编译的过程可以分为词法分析阶断、语法分析阶断、语义分析阶断、源代码优化阶断、生成目标代码阶断、目标代码优化阶断!
这个过程可以通过“我是中国人”这句话来理解!
我是中国人:词法分析阶断,编译器会先将“我是中国人”划分为主语“我”,谓语“是”,宾语“中国人”。
我中国人是:语法分析错误!
我是:语义分析错误
我是一个天真可爱美丽漂亮的中国人:源代码优化阶断会将其优化为我是中国人!
目标代码生成阶断:任何人类能看到的东西、听到的声音,最后都需要转换成生物电,才能被人类所感知,这类似于目标代码生成阶断!
目标代码优化阶断:人类所感知的生物电信号,只要能达到阈值就可以了,超出阈值的部分没有任何意义,这类似于这个阶断!
再通过一些语句来理解这个过程:
1:词法分析阶断
比如语句int Int=1;编译器看到关键字int后知道是一个整型变量,Int代表存储空间,假设为[ebp-4],而1是一个字面常量,“;”表示语句结束!
2:语法分析阶断
比如语句int 1=2;编译器读到1=2时,因为1不能表示一个内存,故会出现语法错误提示!
3:语义分析阶断
比如int;语句,因为没有变量的内存存储空间,所以编译器会出现错误!
4:源代码优化阶断
比如下面的语句:
int a=2;
int b=3;
int c=4;
int d=5;
编译器在源码优化时,会将其优化为int a=2,b=3,c=4,d=5;
5:目标代码生成阶断
比如int Int=1;语句,编译器会生成mov dword ptr ss:[ebp-4],1,mov代表“=”,dword ptr表示是一个32位的数据,即对应整型的变量所对的内存存储空间,ebp-4表示Int标识符所对应的内存空间,1表示字面常量!
5:目标代码优化阶断
比如下面的汇编语句:
1:push 3
2:jmp xxxx
3:nop
会将其优化为call xxxx!
当然上面举的例子有其局限性,关键不在于例子而在于理解这个过程!
3.5:汇编阶断
这个过程中会汇编指令会通过汇编程序(指的是汇编编译器)转换为机器能识别的二进制代码!即obj文件!
3.6:链接阶断
生成的obj文件并不能执行,需要通过链接器将其链接为一个可装入的程序,在Windows平台中可装入程序遵循PE结构,在这个过程中主要将程序需要的库文件与OBJ文件进行整合,每个程序有每个程序的功能,很多个程序可能存在共同的功能,比如输入功能,于是人们将实现输入功能的代码编写为库文件,当需要此功能时直接调用库文件就可以了,这是库概念的提出,最初的库链接方式为static_link,这种方式不利于程序的维护,于是人们提出了动态链接的方法,Windows中的DLL文件即是这种调用方式,同时因为虚拟内存的引入,于是人们发明了一种运行时动态链接,当程序真正需要某一个库文件时代码时才会将库文件载入物理内存,正是因为这种运行时动态链接方式的引用,所以Windows程序在生成OBJ文件时,会加入一个__IMP__标志,链接器根据这个标志对程序进行链接,从而产生运行时可动态链接的可装入文件!
四:阴阳学说与C++
阴阳是中国古典哲学中最经典的概念之一,它具体指的是宇宙中万事万物的统一集合体,有人说中国人发明了二进制,其理由就是阴阳学说!我个人不太推崇这种说法,在我个人看来,阴阳是一个class,而二进制只不过是它的一个object!比如太阳为阳,月亮就为阴,比如月亮圆时为阳,缺时为阴,比如运动为阳,静止为阴,阴阳的例子的确很多很多!当然哲学的意义在于指导人类的学习及创造,所以这里想谈一谈阴阳学说与C++的关系!
前面已经对C++作为编程语言需要解决的问题作了说明,就C++来说,存储的数据为静态的(数据结构),则为阴,而对数据的处理方法为动态的(算法),则为阳,所以人们常说程序=数据结构+算法,实际上是一个阴阳平衡的例子!
4.1:阴阳学说与C++编程思想
结构化程序设计是将大问题分解为小问题的过程,在这个过程中大问题从有变成了无的问题,面象对象程序设计则是将问题抽象为一个类,通过类产生出对象有对象解决问题,这个过程中,人从有到无的抽象出来了类,而问题则通过对象从无到有的实现了解决,即面向对象的本质是从无到有的过程!
结构化程序设计很容易理解,但是面向对象从无到有的过程可能有些费解,我们不妨写一个类,如下:
#define FAST //方便调试
#include "head.h"
class test
{
int a,b;
public:
test(){a=b=1;}
~test(){cout<<"析构函数!"<<endl;}
void Cout(){cout<<a<<" "<<b<<endl;}
};
int main()
{
//什么都不做
return 0;
}
这时候用OD载入,你不会发现类中成员函数任何有效的汇编的指令!所以类是“无”的状态,只有对象才是“有”的状态,编译器从无到有的生成对象,而人则从有到无的抽象出类!
从无到有面象对象程序设计,从有到无结构化程序设计,本身这就是一对阴阳!
让我们回到本章开始处的入门程序,通过这个小例子体会结构化程序设计与面象对象程序设计!
//结构化程序设计过程
1:问题:输出hello world!
2:解决:将问题分解为两个函数hello()和world(),hello()用于输出“hello ”,world()用于输出“world!”,大问题“输出hello world!”没有了,变成了两个小问题,输出“hello ”和输出“world!”(从有到无)!
3:编写代码:
#define FAST
#include "head.h"
void hello(void)
{
cout<<"hello ";
}
void world(void)
{
cout<<"world!"<<endl;
}
int main()
{
hello();
world();
return 0;
}
//面向对象程序设计过程
1:问题:输出hello world!
2:解决:行为抽象输出,有show()实现,数据抽象字符,为string类型,将问题从有到无的抽象出类Cout;问题从有到无的被抽象了,实现有Cout类生成对象,问题有Cout对象,从无到有的解决了!
3:编写代码
#define FAST
#include "head.h"
#include <string>
class Cout
{
string s;
public:
Cout(string arg){s=arg;}
void show(){cout<<s<<endl;}
};
int main()
{
Cout hello("hello world!");
hello.show();
return 0;
}
《道德经》中说“玄而又玄,众渺之门”指的是抽象再抽象即我们抽象出来的东西还可以再次抽象为更复杂的内容,比如上面的面向对象程序设计过程,我们还可以继续抽象为模板:
//抽象再抽象的面向对象程序设计
1:问题:输出hello world!
2:行为抽象输出,数据抽象符号(即任何数据类型)!
3:编写代码:
#define FAST
#include "head.h"
#include <string>
template <typename type> class Cout
{
type s;
public:
Cout(type x){s=x;};
void show();
};
template <typename type> void Cout<type>::show()
{
cout<<s<<endl;
}
int main()
{
Cout<string> hello("hello world!");
hello.show();
return 0;
}
程序在抽象出Cout类后,再次类数据成员抽象为一个类模板!
4.2:阴阳关系与二进制
通过上面的描述,相信朋友们对阴阳理论有了一定的了解,我们再讨论一下阴阳的关系!前面已经提到二进制与阴阳的关系 ,前者为object后者为class,针对这个问题编写如下程序:
//阴阳学说与二进制
#include "head.h"
class yinyang
{
int yin;
int yang;
public:
yinyang(){yin=0;yang=1;}
void and();
void or();
void not();
void xor();
};
void yinyang::and()
{
cout<<"阴阳相克,即0克1"<<endl;
cout<<(yin&yang)<<endl;
}
void yinyang::or()
{
cout<<"阴阳相克,即1克0"<<endl;
cout<<(yin||yang)<<endl;
}
void yinyang::not()
{
cout<<"阴阳相生,即0生1,1生0"<<endl;
cout<<~yin<<" "<<~yang<<endl;
}
void yinyang::xor()
{
cout<<"阴阳互制,即有一个1得1,有两个1得0"<<endl;
cout<<(yin^yang)<<endl;
}
int main()
{
yinyang oneandzero;
oneandzero.and();
oneandzero.or();
oneandzero.xor();
oneandzero.not();
return 0;
}
上面的程序通过阴阳相生、相克、互制与二进制的位运算相结合,相信朋友们会更加理解阴阳学说在C++中的意义!
事实上我个人感觉C++的强大完全在于其强大的阴阳互制上,举几个例子加深对阴阳学说在C++中的应用,比如常量与变量,常量为阴,变量为阳,阴中有阳,符号常量是一种值不变的变量,阳中有阴,变量需要字面常量进行初始化,再比如,运算符中,算术、逻辑、位运算都有固定的优先级为静态的为阴,而()则有修改各种运算符的优先级为动态的为阳,再比如类中的public、private、protected成员都有固定的保护属性为静态的为阴,而友元则可以无限制访问则为阳,而继承则可以重组各种保护属性下的数据成员、成员函数,则是一种平衡阴阳的方法,所以说阴阳无处不在,C++亦是阴阳无处不在,在后面的内容将以本章为纲领继续讨论C++的各种特性!
- 标 题:《剑走偏峰来自一个中国人的C++教程》系列一
- 作 者:reduta
- 时 间:2010-03-15 07:55:12
- 链 接:http://bbs.pediy.com/showthread.php?t=108909