C++与STL入门

今天学的一点C++知识

1.c++版本框架:

c++头文件:

stdio.h ->  cstdio   string ->  cstring   math.h -> cmath  ctype.h  -> cctype

c++ 程序 加  using namespace std;  这句话

这个是什么意思呢? C++中有一个“名称空间”(namespace)的概念,用来缓解复杂程序的组织问题。例如张三写了一个函数叫my_good_function,李四也写了这样一个函数,两个函数参数类型也一样,但作用和张三不同。如果把他们代码合在一起用,就会出问题,一个解决方案是分别把函数写在各自的名称空间里,然后就可以用 zhang3:my_good_function()和li4:my_good_function()这样的方式进行调用了。

我下面写一段话可能就明白名称空间怎么用了。

这两种代码作用的相同的:

C++中可以使用流简化输入输出操作。标准输入输出流在头文件iostream中定义,存在于名称空间std中。如果是使用了using namespace std 语句,则可直接使用。也就是可以用cin代替std:cin,cout代替std:cout,同样min函数存在于algorithm头文件中,min代替std:min直接使用。

最后还有一个细节:声明数组时,数组大小可以使用const声明的常数。在c++中比较推荐这种用法。

2.引用:

如果在参数名之前加一个“&”符号,就表示这个参数按照传引用(by reference)的方式传递,而不是c语言里的传值(by value)方式传递。这样,在函数内改变参数的值,也会修改到函数的实参。

3.字符串:

C++提供了一个新的string类型,用来替代c语言中的字符数组。用户仍然可以继续用字符数组当字符串用,但是如果希望程序更加简单、自然,string类型往往是更好的选择。例如,c++的cin/cout可以直接读写string类型,却不能读写字符数组;string类型还可以像整数那样“相加”,而在c语言中只能使用strcat函数。

string类在string头文件中,而stringstream在sstream头文件中。首先用getline函数读一行数据,然后用这一行创建一个“字符串流”-----ss。接下来只需想读取cin那样读取ss即可。 虽然string和sstream都很方便,但string很慢,sstream更慢,应谨慎使用。

4.集合set和映射map

集合与映射也是常用的容器。set就是数学上的集合--每个元素最多只出现一次。set中的元素也是从小到大排好序了。当然跟sort一样,自定义类型也可以构造set,但同样必须定义“小于”运算符。

map就是键(key)到值(value)的映射。因为重载了[]运算符,map像是数组的“高级版”。例如可以用一个map<string,int> month_name来表示“月份名字到月份编号”的映射,然后用month_name["July"] = 7这样的方式来赋值。

set 和 map 分别是集合与映射。二者都支持insert、find、count和remove操作,并且可以按照从小到大的顺序循环遍历其中的元素。map还提供了“[]”运算符,使得map可以像数组一样使用。事实上,map也称为“关联数组”。

5.随机数的使用

为了随机生成整数,先来看看随机数发生器。核心函数是cstdlib中的rand(),它生成一个闭区间[0,RAND_MAX]内的均匀随机整数(均匀的含义是:该区间内每个整数被随机获取的概率是相同的),其中RAND_MAX至少为32767(2^15-1)。

如何产生[0,n]之间的整数呢?很多人喜欢用rand()%n产生区间[0,n-1]内的一个随机整数,姑且不论这样产生的整数是否仍然分布均匀,只要n大于RAND_MAX,此法就不能得到期望的结果。在使用此法时应当小心。另一个方法是执行rand()之后先除以RAND_MAX,得到[0,1]之间的随机实数,扩大n倍后四舍五入,得到[0,n]之间的均匀整数。这样在n很大时“精度”不好(好比把小图放大后会看到“锯齿”),但对于普通的应用,这样做已经可以满足要求了。

随机数的使用方法:

需要随机数的程序在最开始时一般会执行一次srand(time(NULL)),目的是初始化“随机数种子”。简单地说,种子是伪随机数计算的依据。种子相同,计算出来的“随机数”序列总是相同。如果不调用srand而直接使用rand(),相当于调用过一次srand(1),因此程序每次执行时,将得到同一套随机数。(如果需要程序每次执行时使用一个不同的种子,可以用ctime中的time(NULL)为参数调用srand。一般来说,只在程序执行的开头调用一次srand)。

下面是一个随机程序:

注意srand函数是在主程序开始时调用,而不是每次测试时调用。参数是vector<int>的引用。为什么不把这个v作为返回值,而要写到参数呢?答案是:避免不必要的值被复制。

如果这样写:

实际上函数内的局部变量v中的元素需要逐个复制给调用者。而用传引用的方式调用就避免了这些复制的过程,节省了时间和空间。

6.assert的用法

写完随机数发生器之后,我们可以测试库函数中的sort函数是否正确,程序如下:

新内容是上面的assert宏,其用法是“assert(表达式)”,作用是:当表达式为真时无变化,但当表达式为假时强行终止程序,并且给出错误提示。当然,上述程序也可写成“if(v[i]>v[i+1]) {printf("Error: v[i]>v[i+1]"); abort();}”,但assert更简洁,而且可以知道是由代码中的哪一行引起的,所以测试时常常使用它。

下面是测试的代码:我测了100个随机数,发现没有问题,哈哈,我也不知道sort函数到底有没有问题,这里也只是将随机数跟assert结合用一下。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值