我开发了一个基于 Beancount 的账本托管服务 HostedBeans,欢迎大家来了解纯文本复式记账并试用我的服务。
归档 2012 年 10 月

C++ 讲稿 2.HelloWorld

By 精英王子

CC-BY-NC-SA(署名-非商业性使用-以相同方式共享) 3.0

注:解说在图片下方

原始幻灯片(持续更新):https://docs.google.com/presentation/d/1BOk1KOHcI6Ts345Ja5vAyhSXhHRBRc53FNPnfr1p7fQ/edit

解说写在讲者备注

1

有同学表示上节课太浮云,没啥实际的。

我想说,我讲的都是我认为各位有必要了解的,如果你打算学C++,请端正态度,这里没有哪些是不重要的。

我已经把“预备知识”精简得很少了,其实我可以光讲“预备知识”而十节课不重样。

那么,这节课来点实际的!

2

这个程序的功能是输出一行字“Hello World!”,我们先要了解的是C++的输出功能。

C++提供了一个名叫iostream(input output stream)的组件,这个组件用来控制C++程序的输入和输出。

3

C++的输入和输出是基于一种“流”的概念,这是一个很有趣的概念。

试想,数据(在这里是“Hello World!”这一行字)就好像水流,屏幕就像一根水管。数据从计算机中,由屏幕这个水管流出来。
在你用键盘输入字符时,字符通过键盘流入计算机。

水管的特点就是可以任意组装,(通过后续的学习)你可以轻松地把本来指向屏幕的数据流,接到打印机上打印出来;或者接到文件上,写入到文件;再或者接到网络上,由网络发送数据流。

下面介绍这个(<<)符号,它由两个左尖括号组成,它在这里叫“流插入运算符”.

顺便提一下,C++中每个符号都有多种含义,不同的上下文的情况下,含义和功能不同。

流插入运算符就像一个箭头一样,在这里,它把右边的“Hello World!”插入到了cout中。cout表示标准输出(stdout)(standard output),默认是显示器,从而把“Hello World!”显示在屏幕上。

在C++,以及其他很多编程语言中,文字(Hello World!)必须由双引号括起来,因为计算机(编译器)不知道你是想在屏幕上显示“Hello World!”,还是发出一个叫Hello World!的指令。

“Hello World!”之后还有一个endl(end line),它是一个控制符,姑且我们可以认为它表示一个换行。

4

但事实上,cout和endl并不是C++语法的一部分,C++只提供的最为基础的语法,甚至不包括输入/输出、读写文件、绘制图形、网络操作、复杂的数学运算。在C++标准制定之前,这都需要程序员自己来完成。

为提高开发效率,标准中要求各编译器附带一个“标准库”,来提供上述部分功能。我们这套课程也会介绍标准库中一些功能的使用。标准库可以说是对C++各种语法的最佳实践。

即使编译器中附带了标准库,但如果你没有明确要求使用它,它也绝对不会出现。

开头的#include 表示把iostream这个标准库文件包含进来,这个组件之前介绍过了,用于提供输入输出的功能。

cout就依赖于iostream.

标准库中包含了很多的东西,为了防止你自己编写的代码与标准库发生冲突(如重名),标准库中的东西会被加上std::的前缀。cout事实上应该写成std::cout.

5

就像这样

6

但是对于我们这个不足十行的小程序来说,这么写只会带来麻烦而不是优势。所以我们可以加上这样一句(using namespace std;)代码来省略std::.

这行最后是一个分号,在C++中用分号表示一个语句的结束,而不是通过换行。事实上,C++编译器会忽略所有多余的换行和空格。这可以使人们自由地排版,让代码更容易阅读。

7

不过不建议大家使用过于反人类的排版方式。

8

现在我们已经将这个程序最核心的语句(cout<<&#8220;Hello World!&#8221;<<endl;)介绍完了,这行代码就能完成程序的主要功能,那么剩下几行是干什么的呢?

一个程序可能会有成千上万行代码,复杂的项目,如一个游戏,可能有几十万行代码。那么代码是从哪一行开始运行的呢?

并非想当然地是从头开始,而是从一个叫main(不是MAIN ,也不是mAin,更不是mian)的函数开始执行。这是一个约定俗成的习惯。

函数(function)是编程中一个常见的概念,它和数学上的函数概念有所不同,但也有一些相似,不过即使你对数学中的函数一窍不通,也不会影响你接下来的学习。

函数是程序的重要组成部分,一个程序可以由若干的函数组成,也可以只有一个——main函数。

函数包括了若干条以分号结尾的语句,一个函数被执行时,其中的语句会按照顺序逐个执行。

main函数是一个特殊的函数,它会在程序被打开时,(由操作系统调用)自动开始执行,是整个程序的入口点。

int main() 这是函数头,就像一个函数的自我介绍,一开始的int是“返回值类型”,在这里是int (Integer,整数).

然后是函数的名字,这里是main,最后括号中的是参数列表,在这里是空的。

对上述术语不懂没关系,今后我会细致讲解。

接下来就是main函数的内容,我们称之为函数定义,函数定义可能包含很多行语句,所以我们要用花括号将它们括起来。

一对花括号,以及其中的内容,在C++中表示一个“块”,是一个整体。在这里,这个块就是main函数的函数定义。

还有一句(return 0;),这表示中断(退出)这个函数(main函数)的执行,并提供返回值0给调用者,关于返回值,我们会在讲函数时详细讲。

至此,我们已经介绍完了Hello World这个程序。

9

为了帮助你自己或别人理解你的代码,你可以在代码中加入注释

C++中的注释有两种,一种是以两个斜杠开始,直到这一行结束。

还有一种以一个斜杠和一个星号开始,直到一个星号和一个斜杠,可以跨越多行。

编译器会无视你的注释,应该说注释是写给将来阅读代码的人看的。从某种程度上说,代码也是写给人看的,而不是计算机。

因为计算机只能理解二进制的指令。

10

这是上节课提到的另一个程序,这个程序会从键盘读取连个数字,计算这两个数字的和并输出。

我再介绍一下在命令行上输入数据:输入两个数字,中间以空格隔开,然后按回车,或者每输入一个数字按一次回车。

这个程序和刚才的Hello World差不多。相同的部分不再介绍。

double a,b; 这句的意思是定义两个double类型的变量,分别命名为a和b.

变量(Variable),就是可以在运行时改变的量,是处理数据的基础。

你可以随时把一个值存入变量,也可以随时读取它所存储的值。

变量所存储的值的类型,就是变量的类型。换句话说,变量的类型,决定了变量可以储存什么样类型的值。

这里的类型,可以是整数、浮点数(小数)、字符串(文字)等等.

这里的double表示浮点数,即小数,所以我们这个程序不光可以计算整数的和,还可以计算小数的和。

在定义变量之后就可以使用它了。

cin>>a>>b;

我们又看到了流插入运算符,但怎么是反的?

cin(char input)在这里表示标准输入,一般默认是来自键盘的。

这句代码的意思是让数据由键盘流至a、b这两个变量中。即从键盘读取两个数(小数,这取决与a和b的类型),分别存入a和b.

double c=a+b; 这次我们又定义了一个浮点型变量c,而且直接把它的值设置为a加b的和。

等号在这里叫赋值号,用来把右边的值复制到左边的变量中。而加号就是通常意义的相加。

这句代码其实是下面两句的缩写:

double c;

c=a+b;

cout<<a<<”+”<<b<<”=”<<c<<endl;

这一句看似复杂,但其实是我们学过的东西,

它会输出a+b=c,当然,a、b、c会用它们实际的值来替换。

可以看到,若要使用变量的值,直接写它的名字就可以,而要表示a这个字母,则要加双引号。

11

12

C++ 讲稿 1.预备知识

By 精英王子

CC-BY-NC-SA(署名-非商业性使用-以相同方式共享) 3.0

注:解说在图片下方

原始幻灯片(持续更新):https://docs.google.com/presentation/d/1DdrpO1IJN0n493ZpwnjFftwgSZOmXtL95E3ZtDFnfqc/edit

解说写在讲者备注

附带的演示用文件:https://docs.google.com/open?id=0Bw3FV-5YeU2wWTRwNVNrazhLNlk

1

C++的英文名C Plus Plus,有时也简写做CPP.

万事开头难,也许有的人有兴趣学习编程,但是不知道从哪入手,于是就搁置了下来,今天我就给大家一个了解编程的机会,带领大家入门。

不得不说各位对计算机的了解很少,如果我提到的某个词你没听说过,或者不理解,请随时提问,我来解释。

可以说我对我在C++方面的知识很有信心,其他编程语言也略有涉及,大家有问题可以随时问我,我几乎每天晚上QQ都会在线.

2

众所周知计算机只能理解二进制的指令(这是十六进制的形式,本质也是二进制),而且甚至每个型号的计算机的指令都不一样。.

在计算机被发明的前几十年里,程序员只能通过这样方式与计算机沟通。

这意味着搞编程的人都会疯掉的。

3

被机器码搞疯的人发明了汇编语言。

可以看到,汇编语言中有了比较清晰的结构,可以直接使用十进制的数字,可以直接书写英文单词(比如Hello World),用一些字母缩写代替了二进制的指令。

但是计算机依旧只能理解二进制的指令,所以人们编写了一个程序,用来自动地将汇编语言翻译成机器码,然后交给计算机来执行。

使用汇编语言让程序员方便了很多,但还是有人觉得这样太麻烦。

4

丹尼斯·里奇在1970年发明了C语言,虽然大家可能依旧看不懂,但是C语言已经非常接近自然语言了。很遗憾他在去年(2011年10月12日)这个时候因病去世。

同样,计算机不认识C语言,只认识二进制的机器码指令,所以也需要一个软件将C语言翻译为机器码。

顺便说一下,在汇编语言与C语言之间的时间里,还有很多编程语言被发明出来,不过我们就不一一介绍了。

5

Bjarne Stroustrup觉得C语言用起来很不爽,于是他在C语言的基础上进行了改进,后来称为C++.

可以C++看到和C区别很小,事实上C++是对C的一个扩充,所以绝大部分C代码也可以作为C++代码。

一直以来C和C++(人们常常把他们放在一起讨论)在软件领域具有无可替代的地位,而且这种趋势在今后也会持续下去,C/C++是编程中的必修课程。

这段程序(以及前面的三段程序)的功能是在屏幕上打印”Hello World!”这一行字,翻译成中文就是“你好,世界!”.

丹尼斯·里奇(C语言的发明者)等人所著的计算机程序设计教程《C程序设计语言》(The C Programming Language)中以输出这一行字作为最简单的例子,后来广泛流传,几乎所有编程书籍都以此为例。

6

C++并不属于某个个人或某个组织,任何人都可以去使用它,时间一长就容易出现混乱。

1990年开始ISO(International Organization for Standardization,国际标准化组织)和ANSI(American National Standards Institute,美国国家标准学会)就开始着手将C++的内容进行汇总,指定具有指导意义的“标准”文件,由于C++的内容实在太多,个别部分有很大争议,这项工作历时8年才完成。1998年ISO和ANSI发布了C++的第一个标准C++98.

C++03没有新增内容,只是对C++98中有争议的部分做了修订,并修正了一些漏洞。到目前,C++03是被广泛应用的版本,我们以它为主来了解C++.

C++11是近期才发布的新标准,新增了很多的功能,但是软件厂商还在完善编译器,程序员还在学习,目前应用还不是很广泛,我们会略微提及,但不会太多。

7

没错,C++应用的领域非常广泛,你所使用的软件很大一部分都是由C++编写。尤其是大型游戏,几乎90%以上都是由C++编写。

不光是电脑,包括手机、甚至计算机都有C++的参与。

Windows大部分使用C++编写。

8

演示:运行24.exe

一个算24点的小程序,输入四个数字,输出计算结果为24的算式.

9

应该说我会给大家讲比较前沿、实用的技术,比如新的C++11标准,常见的类库如Boost、Qt等。

在讲C++语法的同时也会研究背后的原理,会很生动、有趣。

这是我这个课程和国内一些比较坑爹的教科书的最大区别。

课程用到的所有文件、幻灯片我都会提供,一般情况下不需要你用笔去记录什么,我也不鼓励这样做。

记忆要建立在理解的基础上。

10

我们编写的代码就叫源代码(Source Code),或者源文件,源文件通过编译器(Compiler)可以翻译成可以运行的程序。

但是这个过程是不可逆的,由程序不能翻译得到源代码。很多商业软件只提供最终的程序,不提供源代码,比如Windows、QQ等。

所以你只能使用这个程序,而不能修改,任何修改都必须修改源文件,然后通过编译器重新生成程序。

也有很多软件在提供程序的同时还会提供源代码,这意味着你可以自由地修改源代码、从而修改程序,改变程序的行为(当然,有时候会受到法律的制约).

这类软件被称为开源软件/自由软件(Free Softwave,这里的free是自由而非免费).

11

前面提到C++不属于任何个人或者公司控制,那么用来从C++翻译到机器码的编译器是由谁编写的呢?

事实上,各大知名的软件公司都各自编写了各自的C++编译器。这三种只是应用比较广泛的,事实上还有很多。

他们都遵守ISO/ANSI指定的C++标准来翻译C++代码,但是也存在一些细微的差别。

GNU即GNU’s Not Unix,是一个递归缩写,这是一个庞大的工程,致力于构建一整套自由软件,G++是它的一部分。

演示:用GCC编译24.cpp

g++ -o 24.exe 24.cpp

即之前那个24点的程序

12

IDE即Integrated Development Environment.

GCC即GNU Compiler Collection,GNU编译套件。

13

本来我是应该让大家自己去它们的官网下载的,但是鉴于这坑爹的网速,我给大家下载好了。

但是我还是要提醒大家,在绝大多数情况下,去官网下载软件才是最方便高效的。

MinGW(GCC)官网:http://www.mingw.org/

这里有个我打包好的版本:https://www.dropbox.com/s/rup6ya4m652k6v6/MinGW-2012.4.26.zip

Qt官网:http://qt-project.org/

需要下载Qt库(Qt libraries)和Qt Creator.

14

15

16

今天讲了很多的东西,很多地方都是一句带过,没有细讲,还有很多的地方我说了“一般情况下”、“通常”。这是因为涉及的领域实在太宽,今后我们会将这节课忽略的各个细节翻出来,研究为什么会是这样,为什么要这样做。

我计划是会讲一学期,不到二十节,这仅仅是C++的一小部分,给大家牵个头。如果有兴趣我们以后就可以聚在一起研究。

有人会问学它有什么用,我也不知道,如果把它当作工作也会是很枯燥的,把它当作兴趣也许会是非常有趣的。我喜欢它的严谨,像数学一样严谨,一就是一,二就是二,确定性是美妙的一件事情。

这一节课我同样学到了很多东西,我以前对很多细节模棱两可,但是为了给大家讲正确的知识,我花了很多时间去查资料,弄懂了以前所不了解的细节。

下一节课的名字叫Hello World,我们会讲这节课提到的几段程序是如何工作的.

灰常冷门的攻击方式:跨端口窃取Cookie

大多数网站,在登陆后会通过Cookie来保存登陆状态如果你能够得到其他人的Cookie,你就可以以他的身份来访问网站.

如果你得到了管理员的Cookie,那么你就可以以管理员的身份来进入后台

访问一个网站时,当一条Cookie满足下面三个规则的时候,这个Cookie就会被发送:

  • 该网站的域名与Cookie要求的域名相同
  • 该网页的路径与Cookie要求的路径相同
  • 该网页的连接方式(HTTP/HTTPS)与Cookie的要求相同

注意!这其中没有与端口有关的要求!

也就是说,浏览器认为 http://xxoo.xo/http://xxoo.xo:1234/ 是同一个网站

http://xxoo.xo/ 设置的Cookie,在访问 http://xxoo.xo:1234/ 时也会被发送

这意味着,如果你能够在 xxoo.xo 对应的ip上的其他端口建立Web服务器,并欺骗 xxoo.xo 的管理员访问你的Web服务器,那么你就可以窃取到管理员的Cookie,进而以管理员的身份来访问网站,进入后台.

如果 xxoo.xo 被托管在一个公用的虚拟主机服务器上,这会非常简单,你可以在相同的服务器上购买一份虚拟主机,甚至试用。然后在其他端口建立一个Web服务器。当然,国内的大多低端主机商恐怕不会提供这个功能。

所以我要给我的神马终端(http://what.jybox.net)打个广告,这是一个权限非常灵活,而价格又非常低的虚拟主机.

很好,现在你在 xxoo.xo 所在的服务器上的 1234 端口建立了一个Web服务器,并写了一个记录Cookie的脚本

下面你只需要欺骗 xxoo.xo 的管理员访问 http://xxoo.xo:1234/ 即可

他会随便访问别人发来,而且看起来很奇怪的地址么?

其实你可以做得很隐蔽,你可以去他的网站,发表一个帖子(如果是论坛)或评论(如果是博客),发一个地址为 http://xxoo.xo:1234/xxoo.png 的图片,图片是会在网页打开的时候自动加载的,而 xxoo.png 是你写的记录Cookie的脚本.

如此一来,竟做得神不知鬼不觉,没几个人会检查网页上每个图片的地址的&#8230;


我想我有必要再给 xxoo.xo 的管理员一点忠告,想避免这种攻击也并不是很困难

方案1.不要和别人共用服务器,自己购买独立的服务器,独立的IP.

这一条是最简单的解决方案,只要你有钱

方案2. 整个网站都使用HTTPS协议,并设置Cookie仅通过HTTPS发送,不得不说,HTTPS是非常有效的,避免信息泄露的技术。不过SSL证书是非常贵的&#8230;.

所以,我有必要在这里给JySSL(https://github.com/jybox/JySSL)打一个广告,这是我创立的,(目前)免费的SSL证书颁发机构

方案3. 使用CDN,CDN相当于一个代理,你需要将你的域名指向CDN,而CDN一般只开放80端口,其他端口的通讯都会被丢弃.

精子生于 1995 年,英文 ID jysperm.

订阅推送

通过 Telegram Channel 订阅我的博客日志、产品和项目的动态:

王子亭的博客 @ Telegram


通过邮件订阅订阅我的博客日志、产品和项目的动态(历史邮件):

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-ND  授权发布。最后生成于 2023-12-20.