一C++基础 1.每个C++文件都有一个或多个函数,一个必须为main 2假定我们的main程序保存在文件progl.cc中,可以用如下命令来编译它 $ CC progl.cc 3C++没有定义IO语句,使用了iostream要使用命令“#include ”,经常使用的io对象为cin和cout, 还有ceer和clog两个io对象共4个io对象。 <<是输出语句,<<运算符至少接受两个运算符,左边为ostream对象,右边为要打印的值 如std::cout<<“enter 2 numbers”<<std::endl等价于 (std::cout<<“enter 2 numbers”)<<std::endl
是输入语句,用法也差不多 4 std::cout中的std::指出cout是定义在std这一命名空间(namepace)里面的 C++ 中引入namespace(名字空间)的概念,主要是为了减少名字冲突的问题,怕用户在命名的时候命名了cout并且和C++中标准库的 C++的cout不一样,就会出现麻烦。所以在前面加一个std::代表这是C++标准库的cout std全称standard:标准的意思(std:C++的标准库) 5 C++和C一样,由while,for,if等等语句 6类所定义的对象可int,char一样可以进行各种操作,例如(用“+”把两个同类型对象加起来,用“>>" "<<"进行输入与输出,用“=”进行赋值等等) 7和类一起定义的方法叫做类方法,通常用实例化的对象的.(点运算符)来调用。
二C++的基本类型和变量 1.基本内置类型:分为整形(包括字符和bool类形)和浮点形 整型:short,int,char,bool 浮点:float,double 其中bool的值为true或者false C++基本的字符类型是char,其他的字符类型用于拓展字符集如char_32用于Unicode字符集 所有的整型前面加一个unsign就是表示无符号的类型比如 unsigned char 执行浮点运算的时候使用double,因为float和double的计算代价差不多但是double的精度比较高 -----------------------------------------------------类型转化------------------------------------------------------------------------------ 在某种情况发生的时候程序会自动进行类型转化例如:bool b=42,此时b的值为true,如下是发生类型转化的情况总结: ①bool b =42,此时b的值是true;赋给b的值是0的时候b的值为false,其他不为0的时候就是true ②int i=b(此时b是bool类型),当b=false的时候i=0;b为true的时候i的值为1 ③把一个浮点数赋给整数类型的时候,会去掉小数点的部分。 ④把一个整数赋给一个浮点数的时候,整数部分保存,小数部分变为0(小数部分每一位0,如果该整数太大超过了浮点数的容量,可能会影响精度 ⑤把257赋给unsigned char的时候,如unsigned char u=257,u的值是257对256取模为1(0到255有256个数) 附:unsigned是指unsigned int范围是[0,4294967295]共4294967296个数,当赋给unsigned类型一个负整数的时候,实际的值为 这个负数加上非负类型的元素总个数(unsigned为4294967295) 程序里面出现上述状况的时候编译器会自动转化 --------------------------------------------------------------变量--------------------------------------------------------------------------------------- ①对象就是一块可以存储数据并有某种类型的内存空间。它可以是类的实例化空间,也可以是int,double等基本变量的内存空间 可以理解为int,double是C++已经定义好的类,int a这条代码可以理解为a为int类的实例化对象 ②如果定义对象的时候没有指定初值,则此时对象就会被赋予一个“默认值”,该情况不唯一 ③C++有一个引用的机制,就是给一个对象起一个名字,而后所有针对引用的操作等价于对相应的对象的操作 如 int i=2; int &h=i; //h是一个int’类型的引用,是int类对象i的另一个名字,任何对h的操作等价于对i的操作 h++; //此时i的值被修改为3 ④指针:和引用不一样,指针是某个对象的地址 (指针是对象的地址,引用和变量名都是对象的名字) 附:某些符号的多重意义: intp:这里的是声明的一部分,p是一个指针变量 int&r:这里的&紧跟着类型int后面,表示&是声明的一部分,r是一个int类型的引用 &r:&是一个取地址的符号,表示得到对象r的地址 *p:是一个解引用符,指拿出地址p对应的对象的值(void是一种可以储存任意对象的内存地址的指针变量,但是做的是有限) 附:前两种声明是复合类型的声明,比一般的 int i这样的声明复杂一些,一个声明指针变量,一个声明引用 ⑤const限定符:const用于定义一个对象,对象对应的值就不会改变,const必须初始化 ⑥类型别名:using,typedef 表示用别的名字来替代某个类型 typedef double DD;就是用DD表示double using DD=double;
⑦auto运算符:编程的时候常常要把表达式的值赋给对象,这时就要知道对象的类型,而这往往是一件比较困难的事情,所以C++就 使用了auto运算符,它会自动计算表达式的值的类型,如: douuble i,j; auto h=i+j; 此时h的值就是double类型 auto &h=j+i; 此时h是一个double类型的引用 (就是说auto是自动声明对象类型的运算符)
⑧decltype运算符:选择并返回操作数的数据类型 我们有时希望得到表达式运算结果的类型,不希望把这个值赋给对象,所以就有了decltype运算符 如:int var; decltype (var) s=1; 这两条代码等价于 int s=1; (decltype是用来得到某个对象类型的运算符)
⑨自定义数据类型struct 和C语言的结构体struct一样,这个struct可以当作是一个类,需要通过类实例化分配对来访问成员变量, 要用到“.”运算符
1.14
⑩cin>>a>>b 表示分别把两个值赋给变量a,b,cout<<a<<B<<c表示打印a,B,c的值,它们可以是字符串, 可以是常量,也可以是变量名。(#include) 11.写程序之前先写一句using namespace std;表示使用C++标准库std里的所有东西 12string类型 ①定义:表示一个可变长的字符串序列string,定义在std中 ②string的操作 (1)使用输入输出流进行IO操作 (2)getline ( istream &is , string &str , char delim ):C++标准库函数 参数设置:is代表一个输入输出流,str表示停止读取的时候把结果赋给str,delim为停止读取的字符标志,默认为‘\n’。 (可用于设计逐行逐字读入程序的设计) (3)s.empty()方法,判断s是否为空 (4)s.size()方法,返回s的字符个数 (5)s[n]:用于访问s的某个字符,从0开始计数 (6)和其他的类型一样有运算符:+(两个字符串合并),!=,,>=,<= !=,,>=,<=都是利用字符在字典的顺序比较的,对大小写敏感
1.15
标准类型库vector(是一种容器) ①定义:标准库类型 vector 表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引, 索引用于访问对象。因为vector"容纳着"其他对象,所以它也常被称作容器(container)。 要想使用 vector,必须包含适当的头文件(#include) (可以看作多个对象的集合体,就是对象的数组,且vector是支持嵌套的) ②初始化方法 vector luffy 就是指定义了一个vector叫luffy,它是int对象的集合,每一个单元是一个int类型,执行默认初始化 vector Str(10):定义一个Str有10个string vector Str{“I”,“love”,“lcy”}:列表初始化Str这一个Str这一个string的vector ③操作(以vector 的实例化s为例) (1)s.empty()方法,判断s是否为空 (2)s.size()方法,返回s所包含对象元素个数 (3)s[n]:用于访问s的某个对象元素,从0开始计数 (4)两个同类型的vector之间可以比较,赋值 (5)s.push_back(t):把一个对象元素t加在vector s后面 (6)对vector的引用操作等价于对vector的本身对象进行操作,修改,C++对对象本身的操作和传参用引用最合适
1.16
①迭代器:迭代器是一种检查容器内元素并遍历元素的数据类型。类似于指针,对于访问容器内的 C++更趋向于使用迭代器而不是下标操作,因为标准库为每一种标准容器(如vector)定义了一种迭代器类型, 而只用少数容器(如vector)支持下标操作访问容器元素,string也支持迭代器 (简要地说,迭代器是一种指向容器内某个元素的数据类型,它的地位和整型,指针并列) ②迭代器类型(以容器v为例子) 下面两个可理解为返回成员变量的函数。 v.begin():负责返回指向v的第一个元素(或第一个字符)的迭代器 v.end():负责返回指向容器"尾元素的下一位置)"的迭代器。(指向一个不存在的尾后元素) 注:v.end()并不是指向最后一个元素,是指向最后一个元素的后面,就是一个标志,这两个迭代器都可看作是成员变量 并且这两个都是常量,不能改变
③迭代器的运算操作(迭代器可以当作指针来理解) :解引用符,可以用来获取迭代器对应的对象元素,如auto a=(A.begin())就是把A的第一个元素赋给a iter->mem:相当于获取iter所指示的元素的mem成员(适用于对象元素是结构体) ==:判断两个迭代器是否指向同一个对象,如果v.begin()==v.end(),则v是一个空容器 迭代器的运算:iter+n得到一个新的迭代器,迭代器指示的新位置与原来相比移动了n个元素 iter-n,iter–,iter++是同一个道理 iter1-iter2:得到的是一个数,表示iter1与iter2所指示的对象之间的距离(没有相加这种用法)
注:1.迭代器也是vector可以使用的一种操作,就是s[n]的一种高级用法 2.v.end()并不是指向一个对象,所以无法进行解引用的操作 所以遍历一个容器的写法可以是while(v.begin()!=v.end()),变化是v.begin()++ 3.指针的操作也类似,一般只有数组有头指针
1.17
用数组初始化vector(int数组,char数组。结构体数组都行) ①标准库函数begin()和end() C+11新标准引入了两个名为 begin 和end的函数。 这两个函数与容器中的两个同名成员功能类似,不过数组毕竟不是类类型,因此这两个函数不是?成员函数。 正确的使用形式是将数组名作为参数∶ 如int array[]={0,1,2,3} begin (array)返回指向数组array首元素的指针, end(array)返回指向array尾元素下一位置的指针, 这两个函数以数组名为参数,分别返回数组头元素位置的指针和尾元素下一位置的指针 ②代码 int arr[] = {11, 32, 41, 25, 67, 100, 88, 233}; // 列表初始化内置数组 vector Array(begin(arr), end(arr));//把arr的元素复制到Array容器里面去
1.18
(1)C++的几个操作符: ->:通过对象的指针来访问对象成员变量的运算符 . 通过对象本身来访问对象成员变量的运算符 :: 这个符号是C++的双冒号,用于表示变量和函数的归属 如std::cin表示std空间里面的输入流, Human::name表示 Human类里面的name属性 sizeof:返回对象所占的字节个数 位操作运算符(都是双目运算符,计算机上的数都是由0,1组成的二进制数,按位或的意思就是两个数每一位都执行或操作) |:按位或 &:按位与 <<:左移运算符,左移的位数由右侧的数决定(如2<<2表示2左移2位)
:右移运算符,右移的位数由右侧的数决定(如2>>2表示2右移2位)
(2)C++的几个新学的语句(其他的if,while,for,swich用法和C一样) ①do while语句:有一些while可能不会进入循环,do while的意思是不管进不进入循环,先执行一次语句 ②break语句(break statement)负责终止离它最近的 while、do while、for或switch语句(只是最近的而已) continue语句也是如此 ③用try,catch和throw处理异常(自己定义如何捕捉) throw:用于抛出一个异常,抛出异常之后就会从try语句块跳转到catch语句里面并中止语句的执行(语句得控制权转移到对应得 catch语句中),如果没有抛出异常就正常执行try语句块的语句,抛出的异常是一个表达式或一个值如b。 throw通常在try语句里面或者在try语句得函数定义里面 catch:用于捕捉异常(参数是一个对象的类型,) 如果throw抛出的是1,那么catch(int)这一个catch的语句就会捕捉到这个异常,如果抛出的是1.0,catch(int) 就捕捉不到了,catch(double) 才捕捉得到。 伪代码 try { statements/里面有throw语句 } catch(int) { statements; } catch(int) { statements; } … 例如:(自己写的一个检测除数异常得代码) #include using namespace std; double fun(int a,int b) { if(b) return a/b; else throw b;//如果b是0,就把b抛出去 } int main() { int a,b; double result; try { cin>>a>>b; result=fun(a,b); cout<<“上述式子计算得结果是”<<result<<endl; } catch(int) { cout<<“除数不应该为0” ; } return 0; } ④#ifdef,#ifndef,#endif语句 (1)#ifdef:一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一 定条件才进行编译,也就是对一部分内容指定编译的条件. 代码 #include using namespace std; #define DEBUG int main() { #ifdef DEBUG /或者是#ifdef DEBUG/ cout << “条件成立,DEBUG已经定义了!” <<endl;(语句①) #else cout << “条件不成立,DEBUG还没定义” <<endl;(语句②) #endif //这一大段代码得意思是如果#define了DEBUG就执行语句①,否则执行语句② return 0; } (2)#ifndef的用法 #ifndef x //先测试x是否被宏定义过 #define x 程序段1 //如果x没有被宏定义过,定义x,并编译程序段 1 #else 程序段2 //如果x已经定义过了则编译程序段2的语句,"忽视"程序段 1 #endif//终止if (3)C++的分离式编译:C++开发中广泛使用声明和实现分开的开发形式,其编译过程是分离式编译,就是说各个 cpp文件完全分开编译,然后生成各自的obj目标文件,最后通过链接器link生成一个可执行的exe文件(只有一个)
|