C++语法入门从HelloWorld讲起•HelloWorld•#includeiostream•intmain(){•std::coutHelloWorld!std::endl;•}头文件•#include引入头文件,用尖括号表示是系统头文件,用双引号表示是目录下的头文件•#includeiostream就是引入iostream•#includeconsts.h就是引入目录下的consts.h•因为C++是从C发展过来的,所以有一定的历史问题,比方说讲C的头文件移植到C++中,大部分情况下,就是将原来的头文件去掉.h后缀再加上c前缀。比方说C语言中的stdio.h放在C++中就成了cstdio。虽然说stdio.h可以用,但是不推荐。常用的头文件•iostream:Input/OutputStreamc++风格输入输出•cstdio:StandardBufferedInput&OutputC风格输入输出•cmath:MathLibaryfromCC数学库•cstdlib:StandardLibraryfromCC标准库•algorithm:STLStandardAlgorithm算法库•iomanip常用的头文件•string:String•vector:Vector•deque:Doubleendedqueue•set:Set&&Multiple-keyset•map:Map&&Multiple-keymap•bitset:Bitset•queue:Queue•stack:Stack主程序•intmain()•main是主函数(主程序)•返回类型必须是int,至于程序末尾的return0;可以不写•注意不要把变量都开在main里面,因为:•1.这是局部变量,其他函数无法访问•2.如果inta[100000];就会爆栈输入输出•std::coutHelloWorld!std::endl;•cout:Standardoutputstream通过重载的来实现输出,cout和cin很方便,只要不断地用和就能够实现输出和读入,不像printf和scanf还有一大堆的参数。•endl:Insertnewlineandflush•为什么要std::呢?因为cout和endl都被包含在一个叫做std的命名空间(namespace)里面,C++开始特有的变量、函数、类、类型都被包含在了std里面,防止冲突。输入输出•竞赛中比较常用的还是C风格的输入输出,当数据量大的时候比较快•#includecstdio•scanf(format,...)•printf(format,...)输入输出•format是一个字符串,里面有些转义符,还有特定格式•%[*][width][modifiers]type•[]表示可省•type常用有下面的几个:•c:单个字符串•d:十进制整数•f:浮点数•s:c风格字符串,也就是char*•modifiers常用有:•l:longlong/double/longdouble•...部分就是前面的格式所对应的变量(如果是scanf的话要传地址)输入输出•假设格式:•(a,1,2)(b,3,4)(c,5,6)......•charch;•inta,b;•输入:scanf((%c,%d,%d),&ch,&a,&b);•输出:printf((%c,%d,%d),ch,a,b);输入输出•读入c风格字符串•charstr[100];•scanf(%s,str);•保留3位小数•printf(%.03f,123.4567);输入输出•等宽输出•printf(%5d%5d,123,456);•123456•printf(%8.2f%8.2f,123.0,456.0);•123.00456.00•printf(%04d%04d,12,34);//高精压位输出时好用!•00120034输入输出•打开文件,程序开头加上:•freopen(input.txt,r,stdin);•freopen(output.txt,w,stdout);•关闭文件•fclose(stdin);•fclose(stdout);输入输出•转义字符:\n换行•\\输出反斜杠字符“\”•\’输出单引号字符•\”输出双引号字符输入输出•建议大家尽量用C风格字符串来读。。。因为读字符会把一些奇怪的东西读进来。。。•cin,cout方便但是速度慢,取消跟stdio的同步可以加快不少速度•ios::sync_with_stdio(false);•加了这句话以后不要把scanf,cin混用namespacestd•如果觉得每次都打std::很烦,那可以把整个std引入:usingnamespacestd;•#includeiostream•usingnamespacestd;•intmain(){•coutHelloWorld!endl;•}•但是会出现一些很囧的情况,比方说left、right、max、min不能作全局变量,因为已经有同名函数了。namespacestd•例:•#includeiostream•usingnamespacestd;•intleft,right;•intmain(){•left=1,right=10;•coutHelloWorld!endl•left''rightendl;•}•这个程序会编译错误,对left和right的引用有歧义。namespacestd•所以另外一种方法就是只引入我们需要简写的:•#includeiostream•usingstd::cout;•usingstd::endl;•intleft,right;•intmain(){•left=1,right=10;•coutHelloWorld!endl•left''rightendl;•}•这样就没问题了。基本类型•整型:•char/short/int/long/longlong•8bit/16bit/32bit/32bit/64bit•在前面加上unsigned变成无符号类型,比方说longlong相当于int64,unsignedlonglong就相当于qword•浮点型:•float/double/longdouble•32bit/64bit/80bit•对应real/double/extended基本类型•字符:•char•布尔:•bool•字符串:•C风格字符串、字面字符串:char*/constchar*•C++风格字符串:std::string字符常量•字符常量:•用单撇号括起来一个字符就是字符型常量,如’a’,’#’•字符型常量职能包括一个字符。•注意c++中单撇号和双撇号是不同的,双撇号表示字符串。单撇号表示字符常量•这里和pascal中的所有都用单撇号不同。字符串常量•字符串常量:用双引号括起来的就是字符串常量。•“abc”在内存中占4字节而不是3字节,因为系统会给他最后加上“\0”作为结束标志。•顺便提醒开字符数组的时候不要开得刚刚好,字符串的末尾是要加上\0的•即:abc\0字符串•“a”是字符串,’a’是字符。•看下面这段程序:•charc;•c=”a”;•这就会报错,因为c是char,而“a”是字符串。结构体•类似于pascal里的record•structname{•inta;•doubleb;•};•nameval;•val.a=1;•val.b=0.4;指针、数组、引用•inta,b;•指针加*号:int*ptr=&a;•数组加[]:intarr[100];•引用加&:int&ref=a;指针•指针可以改变指向的变量,只要类型相同即可,比方说:•ptr=NULL;•ptr=&a;•ptr=&b;•要访问所指向的变量需要解引用,用*号:•*ptr=3;指针•指针可以相加减,比方说•ptr+3对应的地址就是ptr之后3个int大小(4bytes)位置的元素•ptr1-ptr2指针相减可以得到这两个指针之间有多少个所指向类型元素数组•数组只能从下标0开始,数组变量实际上是一个指针,指向数组第一个元素•*arr和arr[0]相同。•arr[i]相当于*(arr+i)引用•引用必须在声明的时候定义,因为引用不能修改所指向的对象。修改引用就会修改所指向变量。•int&ref=a;•ref=3;//a==3指针、数组、引用•需要注意,声明和定义变量的时候若用逗号分割,那么只能是同类型的。•inta,b=3,c;•int*pta=&a,*p=NULL,*ptc=&c;•intd,*ptr;//Error!!!变量命名规则•有两种风格:•max_flow•MaxFlow•即单词用下划线分割,全小写;和单词首字母大写。•C++所有东西都区分大小写!•变量A与变量a是不同的!初始化•直接初始化:•inta(2),b(3);•std::strings1(aaa);•std::strings2(s1);初始化•复制初始化:•inta=2,b=3;•std::strings1=aaa;•std::strings2=s1;•差别主要在类上,直接初始化调用的是构造函数,复制初始化调用的是operator=函数•全局变量会自动初始化,如果是内置类型会初始化为0,类类型会调用类的默认构造函数。const•用const的理由:在语义上强制不可改,编译器可以做适当优化,比方说可以避免复制类对象(有时候代价是很高的)。另外也可以避免编程上的一些小错误(因为const不能改)const•对于指针类型,const比较麻烦:•int*a:指针a可改,指向元素可改•constint*a:指针a可改,指向元素不可改•int*consta:指针a不可改,指向元素可改•constint*consta:指针a不可改,指向元素不可改•看const在*前面或后面表达式•ArithmeticOperators:•+-*/%+-•%为取模•注意:•1.整型/整型=整型,若要得到浮点型得将其转成浮点型:doublec(a/static_castdouble(b));•2.%是否会有负数取决于机器,所以要得到数学模还是得(a%MODER+MODER)%MODER表达式•RelationalandLogicalOperators:•!====!=&&||•注意:•1.&&和||都有短路性质•2.表达式非0非空即为true表达式•BitwiseOperators:位运算•~&^|•注意:不要和逻辑操作符搞混了……取反是~不是!,和或都只有一个表达式•等于操作符具有右结合特性,并且也会返回值•inta,b,c;•a=b=c=0;•等价于a=(b=(c=0));•if(a=b-1):a=b-1,再判断a是否不等于0。•if(a==b-1):判断a是否等于b-1•强烈注意:一开始很容易犯的错误就是==写成=表达式•CompoundAssignmentOperators:•aop=b相当于a=aopb;•算数操作符:+=-=*=/=%=•位操作符:==&=^=|=表达式•IncrementandDecrementOperators:•自增分为前自增和后自增•前自增:inta=++i:i+1,并且a=i的新值•后自增:inta=i++:a=i,并且i+1•自减类似表达式•TheArrowOperator:•假设有某struct(或者class)a,里面有成员member,指向a的指针p,那么要用p调用member就必须先对其解引用再调用member,由于优先级必须加括号:•(*p).member•用箭头操作符可以省去麻烦:•p-member即可表达式•举个例子,我写链表:•structEdge{•intv,w;•Edge*Next;•};•遍历:•voiddfs(constintu){•for(Edge*e=Header[u];e;e=e-Next)•dfs(e-v