c/c++语言

c++11程序demo

Forums: 

img: 

c++11 的程序小 demo, 让 u 快速了解 c++11 的新的特性。

换行符知多少

Forums: 

img: 

在遇到困难之前, us 总会认为自己已经懂得了“宇宙的真理”。me 相信很多人分不清回车和换行,或是说对很多人来说它们都是一样的。键盘的回车键上有个 return ↵ 或是 enter ↵ 标志,在编辑器中敲击回车键显示一个换行的效果。尼玛,O__O"…

c 语言中,或是 ascii 码中,回车符 carriage return (CR) 和换行 line feed (LF, 因为 c 的缘故有时候又写作 newline NL) 是两个不同的字符。 在 unix 系统中 LF 就是换行, 然而在 windows 系统下 CR LF 两个字符才显示一个换行, mac 下貌似是 CR 表示换行。 这没有所谓的对错一说, 不同的系统就是有这样不同的实现, 有时候这会成为一个问题。这里也简单描述一下 c 对回车符 CR 和换行符 LF 的记法:\r 和 \n ,这种转义的记法几乎为后来的所有编程语言所采纳。

不同的换行实现

下面是一个简单的 c 程序:

c语言处理时间和日期

Forums: 

img: 

处理时间和日期很常用, 比如 me 们想简单看一下程序跑的有多快, 比如 me 们想记录日志(通常包括时间),再比如 me 们想知道今天星期几等。 c 的标准库 time.h 提供了处理时间和日期的类型和函数。 先说说 me 的感受吧, c time.h 中提供的日期处理中大量使用了内置于函数的 static 数据,这对于单线程程序来说无所谓,no problem, 但是总让人赶脚不爽 —— 非线程安全。 其次, c 提供的统计时间的函数有时候比较粗糙, 使用 time() 函数基本上只能统计到秒一级, 使用 clock() 函数可以统计到 1/CLOCKS_PER_SEC 秒一级(me 的一个实现是毫秒)。还是让 me 们说正事。

类型

time.h 定义了三种类型和 9 个函数, 内容很少, 不过功能很全。 三种类型: clock_t、time_t 和 struct tm , 前两种是算术类型,也就是类似于 int 或是 double 的类型, 通常应该是整型; 第三种是一个结构体,将日期分离开来。 clock_t 是计算的 cpu 时间, time_t 是日历时间, struct tm 是字段分离的日历时间表示。

c++统计时间

Forums: 

img: 

统计程序运行时间是一个多么常用的一个功能, 然而很多时候么有告诉 us 怎么去做。 c 的 time.h 提供了自己的处理方法, c++11 也引入了自己的方法。 下面就是 c++ 中统计程序运行时间的一个例子。(统计运行时间,实际统计的是程序运行前后的时间差,而非程序跑在 cpu 上的准确时间。)

c++有理数类

Forums: 

img: 

有理数其实就是分数,p/q形式的数。 c/c++ 虽然有整数,浮点数,却没有内置的有理数表示。 为了练习 c++ 类的书写, me 写了个一个简单的有理数类, 可以实现 + - * / 四则运算。

写这个小程序完全是为了练手, 熟练 c++ 的使用。+ - * / 的思路都很简单,和平时 me 们手工计算的思路一样, 不过实现需要知道最大公约数 gcd 和最小公倍数 lcm 。 gcd 的求法使用的是众所周知的“辗转相除法”。

处理 gcd 和 lcm 之外,程序更多的部分是重载 + - * / += -= *= /= 四则运算符, 和流输出 << 运算符, 以及在不够减的时候抛出异常。

下面的代码仅供参考:

自定义字面量

Forums: 

img: 

字面量 literal 就是诸如 1234 、 0xfe、 3.14 、 2.71828f、 "hello,world"、 'x' 这样的量,这些都是对应类型的书写常量。 在数学或是物理中, 除了整数和浮点数表示外, me 们还常见诸如 1+2i 、32 kg 这样的表示,学汇编的恐怕还熟悉 10110011b 这样的表示(二进制形式)。 本来 c++ 从 c 那里只继承了一些基本类型的一些固有的表示方法,不过 c++11 对于这种功能进行了扩展,也就是 me 们可以自定义一些数据表示形式,比如 1+2i 表示复数, 1011b 是整数的二进制表示。

c++ 的这种扩展是通过运算符 "" 的重载实现的。下面是一个复数 a+bi 表示的程序 demo :

元编程

Forums: 

img: 

所谓的元编程(metaprogramming),就是编写能够操控其他程序的程序,或是编写编译期就能完成运行期任务的程序。编译器和解释器是前者的典型,而 c++ 的模板元编程是后者的典型。元编程在有些地方可以节省程序员不少时间,因为程序可以是“自动生成”的;有的时候可以提高运行效率,比如编译生成的可执行文件中已经完成了一些低级而耗时的工作;有时候可以提高程序的灵活性。

能够用来编写元编程的语言叫元语言(metalanguage),也就是它们能够操控其他语言写的程序;被操控的语言叫对象语言(object language)。一门语言可以操控自己的技术叫做,反射(reflection)或是自反, Java、Golang 都提供放射功能。

元编程一般的工作方式有三种:

可变参数模版

Forums: 

img: 

通常 c 或是 c++ 函数的参数个数和类型都是固定的, 比如 int add(int a, int b); 带有两个 int 的参数 a、 b 。 为了处理传递任意个参数的情况, c 提供了一种方式,比如 printf 的方式。 然而 c 的这种方式是非类型安全的,当 me 们 printf("%d", i); 的时候, 编译器么法去检查 i 是否是整数类型;即使它不是, 这里的调用也是能编译通过的。 c++ 当然还可以使用 c 的技术,然而又提供新的处理方法:可变参数的模板, 也就是模板的参数可以任意多。 实际上 c++ 的可变参数模版和 c 的处理可变参数的某些写法有些类似。

下面是一个 print 的例子, 使用 c++ 书写, 功能就是将传递的参数全部输出。

统计单词个数

Forums: 

img: 

统计单词个数

这是一个描述灰常简单的题目,就是统计文件中的所有单词,以及出现的次数。这里不考虑标点符号等特殊字符的存在,认为文件中只有一个个的单词。题目说简单比较简单,就是统计一个文件中的单词数目,说复杂可能复杂些,比如单词数目很多,就应该考虑效率的问题;再者想象一下如果有成千上万个文件,这个时候的思路跟一个文件的思路就又大不一样勒。

简单做法

现在考虑简单的情形,统计一个文件中的单词数目。me 们线性组织一个单词薄,然后扫描文件;对于每个单词,首先在单词薄中顺序查找,如果找到那么对应的单词数目加 1,如果没有找到,在单词薄中添加一个新的单词并且数目置为 1 ,直到文件中的所有单词扫完。下面的程序就是采用这个思路,从 input.txt 中读取单词,统计,最后再对单词进行排序,然后按字母表顺序输出。

STL:标准模版库

Forums: 

img: 

STL:标准模版库

STL,Standard Template Library,是 C++ 标准库的一部分,主要包括容器类、算法、函数对象、迭代器等的一些东西,是泛型编程的典范。C 的标准库内容过于有限,内置的数组类型并不是很好用,关键是 C 需要程序猿自己管理内存,这是一件灰常麻烦的事;所以如果可以的话就使用 C++ 的标准库,特别是 STL 部分。

容器类

所谓容器,就是说可以向其中添加东西的东西,比如 vector、list、map 等;在其他语言中和容器相似的概念可能是集合类、数据结构等。容器类分为两大类:序列容器和非序列容器。序列容器就是说其中的东西是一个序列 e1 e2 e3 ... ek...。非序列容器则包括 set 和 map 两类,set 就是集合了,没有顺序一说;map 则是 key-value 对,也没有顺序一说。

Pages