第一个C++程序
#include <iostream>
int main ( )
{
std:: cout << "Hello 系统学习C++第一天!\n" ;
}
注释
单行
多行
变量和常量
#include <iostream>
#define MAX 0x3f3f3f3f3f
const long long MAXX = 0x3f3f3f3f3f ;
int main ( )
{
int a = 5 ;
std:: cout << MAX<< " " << MAXX<< " " << a<< endl;
}
标识符命名
1. 标识符不能是关键字
2. 只能有字母、数字和下划组成
3. 第一个字符只能是字母或者下划线
4. 字母区分大小写
5. 要具有见名知意,具有可读性
数据类型
简介
使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。
您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。
类型 关键字 布尔型 bool 字符型 char 整型 int 浮点型 float 双浮点型 double 无类型 void 宽字符型 wchar_t
其实 wchar_t 是这样来的:
typedef short int wchar_t ;
所以 wchar_t 实际上的空间是和 short int 一样。
一些基本类型可以使用一个或多个类型修饰符进行修饰:
signed
unsigned
short
long
下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。
注意:不同系统会有所差异,一字节为 8 位。
注意:long int 与 int 都是 4 个字节,因为早期的 C 编译器定义了 long int 占用 4 个字节,int 占用 2 个字节,新版的C/ C++ 标准兼容了早期的这一设定。
整型
短整型
short num1 = 22 ; 字节数:2 个 范围: - 32768 ~ 32767 - 2 ^ 15 ~ 2 ^ 15
整型
int num1 = 44444 字节数:4 个 范围:- 2147483648 ~ 2147483647 - 2 ^ 31 ~ 2 ^ 31
长整型
long num = 444 字节数:4 个 范围:- 2147483648 ~ 2147483647 - 2 ^ 31 ~ 2 ^ 31
长长整型
long long num = 4444 字节数:8 个
范围:- 9223372036854775808 到 9223372036854775807 - 2 ^ 63 ~ 2 ^ 63
无符号整型
unsigned int = 123; 字节数:4个 范围:0~4294967295 0~2^32
其他的类型的类型,将负数范围补充到正数范围。
关键字–sizeof
#include <iostream>
#include <limits>
using namespace std;
int main ( )
{
cout << "type: \t\t" << "************size**************" << endl;
cout << "bool: \t\t" << "所占字节数:" << sizeof ( bool ) ;
cout << "\t最大值:" << ( numeric_limits< bool > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< bool > :: min) ( ) << endl;
cout << "char: \t\t" << "所占字节数:" << sizeof ( char ) ;
cout << "\t最大值:" << ( numeric_limits< char > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< char > :: min) ( ) << endl;
cout << "signed char: \t" << "所占字节数:" << sizeof ( signed char ) ;
cout << "\t最大值:" << ( numeric_limits< signed char > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< signed char > :: min) ( ) << endl;
cout << "unsigned char: \t" << "所占字节数:" << sizeof ( unsigned char ) ;
cout << "\t最大值:" << ( numeric_limits< unsigned char > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< unsigned char > :: min) ( ) << endl;
cout << "wchar_t: \t" << "所占字节数:" << sizeof ( wchar_t ) ;
cout << "\t最大值:" << ( numeric_limits< wchar_t > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< wchar_t > :: min) ( ) << endl;
cout << "short: \t\t" << "所占字节数:" << sizeof ( short ) ;
cout << "\t最大值:" << ( numeric_limits< short > :: max) ( ) ;
cout << "\t\t最小值:" << ( numeric_limits< short > :: min) ( ) << endl;
cout << "int: \t\t" << "所占字节数:" << sizeof ( int ) ;
cout << "\t最大值:" << ( numeric_limits< int > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< int > :: min) ( ) << endl;
cout << "unsigned: \t" << "所占字节数:" << sizeof ( unsigned ) ;
cout << "\t最大值:" << ( numeric_limits< unsigned > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< unsigned > :: min) ( ) << endl;
cout << "long: \t\t" << "所占字节数:" << sizeof ( long ) ;
cout << "\t最大值:" << ( numeric_limits< long > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< long > :: min) ( ) << endl;
cout << "unsigned long: \t" << "所占字节数:" << sizeof ( unsigned long ) ;
cout << "\t最大值:" << ( numeric_limits< unsigned long > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< unsigned long > :: min) ( ) << endl;
cout << "double: \t" << "所占字节数:" << sizeof ( double ) ;
cout << "\t最大值:" << ( numeric_limits< double > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< double > :: min) ( ) << endl;
cout << "long double: \t" << "所占字节数:" << sizeof ( long double ) ;
cout << "\t最大值:" << ( numeric_limits< long double > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< long double > :: min) ( ) << endl;
cout << "float: \t\t" << "所占字节数:" << sizeof ( float ) ;
cout << "\t最大值:" << ( numeric_limits< float > :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< float > :: min) ( ) << endl;
cout << "size_t: \t" << "所占字节数:" << sizeof ( size_t) ;
cout << "\t最大值:" << ( numeric_limits< size_t> :: max) ( ) ;
cout << "\t最小值:" << ( numeric_limits< size_t> :: min) ( ) << endl;
cout << "string: \t" << "所占字节数:" << sizeof ( string) << endl;
cout << "type: \t\t" << "************size**************" << endl;
return 0 ;
}
实型
科学计数法
3e2 = 3 * 10 ^ 2
3e-2 = 3 * 10 ^ - 2
单精度
float 4 个字节 精度型占4 个字节(32 位)内存空间
+ / - 3.4 e + / - 38 ( 7 位有效数字)
双精度
double 8 个字节 双精度型占8 个字节(64 位)内存空间
+ / - 1.7 e + / - 308 ( 15 ~ 16 位有效数字)
长双精度
long double 16 个字节 长双精度型 16 个字节(128 位)内存空间
可提供18 - 19 位有效数字。
细节
因为编译器的小数默认是double ,编译时会先从double 转化为float
float a = 3.14f ;
double b= 3.14 ;
字符型
作用:
显示单个字符
语法:
char ch = 'a' ; 字节:1 个 范围: - 128 到 127 或者 0 到 255
注意:
用单引号括字符,不能用双引号,单引号内只能有一个字符,不能有字符串
ascii码和转义字符
char ch = 'a' ;
cout<< ch<< " " << ( int ) ch<< endl;
\n
\t
\\
字符串
char str[ ] = "hello world" ;
cout<< str<< endl;
string str = "hello world" ;
cout<< str<< endl;
布尔(bool)
bool flag = true ( 本质是1 ) ;
cout<< flag<< endl;
数据输入
标准输入流(cin)
预定义的对象 cin 是 iostream 类的一个实例。cin 对象附属到标准输入设备,通常是键盘。cin 是与流提取运算符 >> 结合使用的,
int a;
cin>> a;
cout<< a;
运算符
算式运算符
运算符 描述 实例 + 把两个操作数相加 A + B 将得到 30 - 从第一个操作数中减去第二个操作数 A - B 将得到 -10 * 把两个操作数相乘 A * B 将得到 200 / 分子除以分母 B / A 将得到 2 % 取模运算符,整除后的余数 B % A 将得到 0 ++ 自增运算符 ,整数值增加 1A++ 将得到 11 – 自减运算符 ,整数值减少 1A-- 将得到 9
注意:
1. 整数/ 整数= 整数。
2. B = A++ ,先赋值再自增。B = ++ A,先自增在赋值。
3. 只有整型可以进行取模
关系运算符
运算符 描述 实例 == 检查两个操作数的值是否相等,如果相等则条件为真。 (A == B) 不为真。 != 检查两个操作数的值是否相等,如果不相等则条件为真。 (A != B) 为真。 > 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 (A > B) 不为真。 < 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 (A < B) 为真。 >= 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 (A >= B) 不为真。 <= 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 (A <= B) 为真。
逻辑运算符
运算符 描述 实例 && 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A && B) 为假。 || 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 (A || B) 为真。 ! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 !(A && B) 为真。
位运算
位运算符作用于位( 二进制) ,并逐位执行操作。& 、 | 和 ^
假设如果 A = 60 ,且 B = 13 ,现在以二进制格式表示,它们如下所示:
A = 0011 1100
B = 0000 1101
-- -- -- -- -- -- -- -- -
A& B = 0000 1100
A| B = 0011 1101
A^ B = 0011 0001
~ A = 1100 0011
下表显示了 C++ 支持的位运算符。假设变量 A 的值为 60 ,变量 B 的值为 13 ,则:
运算符 描述 实例 & 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 (A & B) 将得到 | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 (A | B) 将得到 61,即为 0011 1101 ^ 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 (A ^ B) 将得到 49,即为 0011 0001 ~ 二进制补码运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0。 (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 << 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 A << 2 将得到 240,即为 1111 0000 >> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 A >> 2 将得到 15,即为 0000 1111
赋值运算符
运算符 描述 实例 = 简单的赋值运算符,把右边操作数的值赋给左边操作数 C = A + B 将把 A + B 的值赋给 C += 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 C += A 相当于 C = C + A -= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 C -= A 相当于 C = C - A *= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 C *= A 相当于 C = C * A /= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 C /= A 相当于 C = C / A %= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C %= A 相当于 C = C % A <<= 左移且赋值运算符 C <<= 2 等同于 C = C << 2 &= 按位与且赋值运算符 C &= 2 等同于 C = C & 2 >>= 右移且赋值运算符 C >>= 2 等同于 C = C >> 2 ^= 按位异或且赋值运算符 C ^= 2 等同于 C = C ^ 2 |= 按位或且赋值运算符 C |= 2 等同于 C = C | 2
杂项运算符
运算符 描述 sizeof sizeof 运算符 返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。Condition ? X : Y 条件运算符 。如果 Condition 为真 ? 则值为 X : 否则值为 Y。, 逗号运算符 会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。.(点)和 ->(箭头) 成员运算符 用于引用类、结构和共用体的成员。Cast 强制转换运算符 把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2。& 指针运算符 & 返回变量的地址。例如 &a; 将给出变量的实际地址。* 指针运算符 * 指向一个变量。例如,*var; 将指向变量 var。
符号优先级
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。
下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
类别 运算符 结合性 后缀 () [] -> . ++ - - 从左到右 乘除 * / % 从左到右 加减 + - 从左到右 移位 << >> 从左到右 相等 == != 从左到右 位与 AND & 从左到右 位异或 XOR ^ 从左到右 位或 OR | 从左到右 逻辑与 AND && 从左到右 逻辑或 OR || 从左到右 条件 ?: 从右到左 赋值 = += -= *= /= %=>>= <<= &= ^= |= 从右到左 逗号 , 从左到右
流程结构
选择结构
if语句
if ( boolean_expression)
{
}
else
{
}
if ( boolean_expression)
{
}
else if ( boolean_expression1)
{
}
else if ( )
. . . . .
if ( boolean_expression 1 )
{
if ( boolean_expression 2 )
{
}
}
switch语句
switch ( expression) {
case constant- expression :
statement ( s) ;
break ;
case constant- expression :
statement ( s) ;
break ;
default :
statement ( s) ;
}
switch 语句必须遵循下面的规则 :
switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。 case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。 不是每一个 case 都需要包含 break 。如果 case 语句不包含 break ,控制流将会 继续 后续的 case,直到遇到 break 为止。 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
循环结构
while
while ( condition)
{
statement ( s) ;
}
do while
do
{
statement ( s) ;
} while ( condition ) ;
for
for ( init; condition; increment )
{
statement ( s) ;
}
int my_array[ 5 ] = { 1 , 2 , 3 , 4 , 5 } ;
for ( int & x : my_array)
{
x * = 2 ;
cout << x << endl;
}
for ( auto & x : my_array) {
x * = 2 ;
cout << x << endl;
}
循环控制
控制语句 描述 break 语句 终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。 continue 语句 引起循环跳过主体的剩余部分,立即重新开始测试条件。 goto 语句 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。
数组
一维数组
数组名的作用:
1.可以统计整个数组的在内存的长度 sizeof(arr);
2.可以获取数组在内存的首地址
int a[ 100 ] ;
double balance[ 5 ] = { 1000.0 , 2.0 , 3.4 , 7.0 , 50.0 } ;
double balance[ 5 ] = { 1000.0 } ;
double balance[ ] = { 1000.0 , 2.0 , 3.4 , 7.0 , 50.0 } ;
cout<< balance[ 0 ] << endl;
二维数组
数组名的作用:
1.可以统计整个数组的在内存的长度 sizeof(arr);
2.可以获取二维数组在内存的首地址
int a[ 3 ] [ 4 ] = {
{ 0 , 1 , 2 , 3 } ,
{ 4 , 5 , 6 , 7 } ,
{ 8 , 9 , 10 , 11 }
} ;
int a[ 3 ] [ 4 ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 } ;
int val = a[ 2 ] [ 3 ] ;
动态数组–vertor
向量容器vector
动态数组,运行阶段设置长度 具有数组的快速索引 可以插入和删除
定义和初始化
vector < double > vec1;
vector < string > vec2 ( 5 ) ;
vector < int > vec3 ( 20 , 998 )
常用操作
初见迭代器iterator
函数
函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main ( ) ,所有简单的程序都可以定义其他额外的函数。
您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat ( ) 用来连接两个字符串,函数 memcpy ( ) 用来复制内存到另一个位置。
函数还有很多叫法,比如方法、子例程或程序,等等。
函数定义
return_type function_name ( parameter list )
{
body of the function
}
在 C++ 中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:
**返回类型:**一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void 。 **函数名称:**这是函数的实际名称。函数名和参数列表一起构成了函数签名。 **参数:**参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。 **函数主体:**函数主体包含一组定义函数执行任务的语句。
函数声明
return_type function_name ( parameter list ) ;
函数参数
如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数 。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
当调用函数时,有三种向函数传递参数的方式:
调用类型 描述 传值调用 该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。 指针调用 该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。 引用调用 该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
默认情况下,C++ 使用传值调用 来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的参数。之前提到的实例,调用 max() 函数时,使用了相同的方法。
参数的默认值
#include <iostream>
using namespace std;
int sum ( int a, int b= 20 )
{
int result;
result = a + b;
return ( result) ;
}
int main ( )
{
int a = 100 ;
int b = 200 ;
int result;
result = sum ( a, b) ;
cout << "Total value is :" << result << endl;
result = sum ( a) ;
cout << "Total value is :" << result << endl;
return 0 ;
}
Lambda表达式
C++ 11 提供了对匿名函数的支持, 称为 Lambda 函数( 也叫 Lambda 表达式) 。
Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:
[ capture] ( parameters) - > return - type{ body}
例如:
[ ] ( int x, int y) { return x < y ; }
如果没有返回值可以表示为:
[ capture] ( parameters) { body}
例如:
[ ] { ++ global_x; }
在一个更为复杂的例子中,返回类型可以被明确的指定如下:
[ ] ( int x, int y) - > int { int z = x + y; return z + x; }
本例中,一个临时的参数 z 被创建用来存储中间结果。如同一般的函数,z 的值不会保留到下一次该不具名函数再次被调用时。
如果 lambda 函数没有传回值(例如 void ),其返回类型可被完全忽略。
在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++ 变量传递有传值和传引用的区别。可以通过前面的[ ] 来指定:
[ ]
[ x, & y]
[ & ]
[ = ]
[ & , x]
[ = , & z]
另外有一点需要注意。对于[ = ] 或[ & ] 的形式,lambda 表达式可以直接使用 this 指针。但是,对于[ ] 的形式,如果要使用 this 指针,必须显式传入:
[ this ] ( ) { this - > someFunc ( ) ; } ( ) ;
实例
#include <algorithm>
#include <cmath>
void abssort ( float * x, unsigned N) {
std:: sort ( x, x + N,
[ ] ( float a, float b) {
return std:: abs ( a) < std:: abs ( b) ;
} ) ;
}
第一天学习小结
也是因为acm的原因,在大一寒假的时候学了一下c++,但也只是简单的基础的用法,没有很系统的学习,当时主要是为了提高写代码的速度和方便,因为c++有stl。但是c++终究也是一门面向对象的语言,可以说之前对c++的认识其实还是基于c的拓展上,基本上都还没算入门,在学了java之后突然对c++这个面向对象也有了兴趣,因为一直用的c++打acm,虽然用不上面向对象,但是对其也是有一定执念的。所以打算趁着这段空闲的时间,搞他一波。由于c++是c的拓展,一些基础的语句语法很相似,我也就没说的很详细了,就简单快速的过了一遍,也有几个点还不错,如vector和lambda表达式。第一天就先到这里吧,明天就是指针和文件差不多,再后面就可以开始new一个对象了,hhhh…