ACwing C++语法笔记打卡第一节
一、c++代码整体介绍
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
cout <<"Hello World"<<endl;
return 0;
}
endl
同样属于<iostream>
main
函数是函数的入口;- 万能头文件
#include <bits/stdc++.h>
;
二、 变量
- 变量必须先定义,才可以使用,不能重名。
- 变量的含义∶程序可以记录的信息;
- 变量类型∶
- 布尔值
bool false/true
, 1byte - 字符型
char
'c'
'a'
'\n'
,1byte - 整数型 int -231— 231-1(-2147483648——2147483647)4byte
- 浮点型 float 1.23,1.235e2 单精度浮点数,有效数字6—7位,8byte
- 双精度浮点数 double 15—16位有效数字,8byte
- 更长的整数型 long long -263—263-1,8byte
- 更长的double类型 Long double 18—19位有效数字, 16byte
- 布尔值
- 定义变量要先声明变量类型:
int a,b=2,C=b;
float d=1.5,e=1,f=1.23e2;
long long l=1231231;
long double m=123.45;
- 浮点型可以表示科学计数法;
- 1 B(yte)= 8 b(it)
- 如果int 类型存不下,需要加上
LL
或ll
转变为long long
类型的常数,不加ll
值可能变为负数(参考java语言); - 末尾加上
f
(float f1 = 3.14f)表示强制为浮点数float
; - 尽量在做题时选择
double
而不是float
,因为float
的精度很低,有效数字是6-7位,而double
的有效数字是15-16位; - 变量定义方式:
变量类型的声明+变量/赋值表达式;
举例:
#include <iostream>
using namespace std;
int main()
{
int a = 5;
int b, c = a, d = 10 / 2;
return 0;
}
三、输入输出
3.1 整数的输入输出
输入变量相加的代码
# include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >>b; //cin的值输入a和b中
cout<< a+b <<endl; // 输出
return 0;
}
endl是回车的意思,同样输入到cout中;
3.2 字符串的输入输出
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin >> str;
cout << str;
return 0;
}
3.3 输入输出多个不同类型的变量
#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout<< a+b <<' '<< a*b <<endl;
return 0;
}
先输出a+b,在输出a*b;
#include<iostream>
using namespace std;
int main()
{
int a,b;
cin >> a;
cin >> b;
cout << a+b;
cout << ' ';
cout << a*b << endl;
return 0;
}
# include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("a+b=%d\na*b= %d\n",a+b,a*b);
\\ 小数写法
printf("a+b=%.1f\na*b= %.2f\n",a+b,a*b);//保留几位小数就.x
return 0;
}
&
是取地址符;- 不论是用空格隔开的整数,还是每行一个整数,
scanf
都能读出来(只要被隔开,隔多少都可以); scanf
在读入字符时,不会自动过滤空格、回车和制表符。
3.4 字符的输入输出
# include <cstdio>
#include <iostream>
using namespace std;
int main()
{
char a,b;
scanf("%c%c",&a,&b);
printf("%c %c\n",a,b);
return 0;
}
scanf
和cin
在读取字符时不同。scanf
不会自动过滤空格和回车。scanf
中%c%c
会读入空格(例如输入a<space>c
,输出a<space>
),%d%d
不会读入空格,因此读入数据和字符的代码为int a,b; char c ; scanf("%d%d %c", &a, &b, &c);
;cin
和scanf
的区别在于cin
会过滤空格(例如输入a<space><space> <space> <space> c
,输出ac
),不用判断数据类型,而scanf
不会过滤输入的空格,且需要判断数据类型int a,b; char c ; cin >> a >> b >> c
。- 算法笔试中,所有能用
cin/cout
的地方一定可以替换为scanf/printf
,反之不能;cin/cout
在运行效率方面远低于scanf/printf
,在输入的数据量特别大时,使用cin/cout
可能会超时。对cin/cout
采用取消同步的优化方式后在某些情况下还是有差距。 - double类型在
scanf
中表示为%lf
; - long long类型在
scanf
中表示为%lld
; - bool类型被作为整数处理,1是True,0是False;
- java中没有
%ld
和%lf
;
3.5 cout格式化输出
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int x, y;
double price[6] = {0, 4, 4.5, 5, 2, 1.5};
cin >> x >> y;
cout << "Total: R$ " << fixed << setprecision(2) << price[x] * y;
return 0;
}
四、加减乘除
整数除以整数是整除;
两个浮点数相除是浮点数;
4.1 整数的加减乘除四则运算
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 6 + 3 * 4 / 2 - 2;
cout << a << endl;
int b = a * 10 + 5 / 2;
cout << b << endl;
cout << 23 * 56 - 78 / 3 << endl;
return 0;
}
- 除法如果是两个浮点数是除法,两个整数相除则是整除;
- c++中取模运算如果被除数是负的(-5),那么余数就是负的,正的就是正的,除数的正负不影响(5%2=1;-5%2=-1;5%-2=1);
mod
函数(取余)只对整数有用,对浮点数会报错;
4.2 浮点数(小数)的运算:
#include <iostream>
#include <string>
using namespace std;
int main()
{
float x = 1.5, y = 3.2;
cout << x * y << ' ' << x + y << endl;
cout << x - y << ' ' << x / y << endl;
return 0;
}
-
浮点数的比较问题:
- 计算机里面存的整数都是精确值,但是浮点数是非精确的。
- 浮点数在计算机中按 科学计数法 的方式按照有效数字存储(如1.2345*10e6)。
- 浮点数的有效数字是一样的但不是精确的相等。因此在比较两个浮点数是否相等时,需要加上容忍的误差(一般设置
|x-y|<10^-6
),例如:#include <iostream> #include <cmath> using namespace std; const double eps = 1e-6; 常量 int main() { int a = 3; float b = sqrt(a) * sqrt(a); printf("%.10f\n",b); if(fabs(a-b) <= eps) puts("相等"); else if (a < b-eps) puts("小于"); else puts("大于"); return 0; }
-
浮点数运算时可能精度丢失:
- 原因:
- 1、将十进制结果转换成二进制。例如十进制结果是2.7,由于2.7无法用二进制精确表示,因此出现第一次精度丢失。已开始定义的浮点数就是一个近似值,0.01实际是0.010000000000012这样的数,但是如果用减法的话会导致最后我们看到的n显示是0.01但是他实际是一个近似0.01的一个数,但比0.01小,因为定义的比所显示的大所以你加上0.00001就解决了这个问题,这样可以使原来不够除的数够除了。
- 2、保存数据,double只能保存小数点后23位,多余的部分被丢弃了,因此出现第二次精度丢失;
- 3、 类型转换,将double类型强制转换为int类型;
- 方法:
- 1、使用整数替代浮点数。二进制整数可以完整的表示所有十进制整数,不存在精度丢失问题,因此我们可以将小数位数固定或者较少的数字转换成整数存储。比如存储货币金额,如果存储单位是元,则需要保留两位小数,例如23.45元。如果将单位改成分,则可以完全使用整数存储,例如2345分。
- 2、使用特殊类处理高精度运算。例如JAVA中的Bigdecimal类。不过要注意,使用这些特殊类虽然可以解决精度问题,但有可能带来其它问题,JAVA中的Bigdecimal类在处理性能上就比float和double要低很多。
- 3、浮点型数据比较的时候不要用等号。例如:
i - 10.0 <= 0.0000000001
这样就会减少点误差。精度丢失发生在都仅仅发生在末位,则一般情况下,我们使用的有效数据精度不会到达六位。那么可以选择一个有效数据精度以外的数值来进行范围选择。如:一般需要的有效精度是3个小数。
那么,判断一个浮点数是否是0就写成if ( x>0.0001 && x < -0.0001)
- 4、数据传递最好使用字符串来传递,如果使用浮点型的话,数据精度可能会存在问题。
- 5、获取其运算值
35.5 - 35.4 = 0.099998
这个数据如果被放大十倍后强制转为整数,结果就是0
,但是实际上应该想要的是1
,这将会是一个很严重的bug(为什么会有放大N倍转整,这是一个很常见的协议格式,在许多设备中都有使用).
解决办法仍然是选择一个在有效精度以外的数值来取消这种精度丢失的影响。如:(35.5 - 35.4) + 0.001 = 0.100998
这样再放大转整就能得到正确的值。 - 6、使用
double x=a/p[i]; c[i]=(int)(x+0.00001);
强转。
4.3 整型变量的自增、自减:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 1;
int b = a ++ ;
cout << a << ' ' << b << endl;
int c = ++ a;
cout << a << ' ' << c << endl;
return 0;
}
int c = a ++;
:c是原来的值,a+1,先赋值再加一;int c = ++ a;
:c和a都+1,先加一再赋值;b = b+a;
可以简写为b += a;
b = b-a;
可以简写为b += a;
b = b*a;
可以简写为b *= a;
b = b / a;
可以简写为b /= a;
b = b % a;
可以简写为b %= a;
4.4 变量的强制类型转换
- float 转为double没有问题,反向则会损失精度;
- int转为float 没有问题,反之向下取整;
- int 转char 根据ASCII码表转换(a-97,A-65);
int a = 5;
float b = (float)a;
int c = 97;
char t = (char)c;
char c = 'A';
cout << (char)(c+32); //char和整数运算会变为浮点数
int a = 6;
float b = 1.3;
cout << a*b << endl; //结果为浮点数7.8
- 隐性的类型转换关系:
- int + float / double = float / double
- char + int = int
- int + long long = long long
- float + double = double
#include <iostream>
#include <string>
using namespace std;
int main()
{
float x = 123.12;
int y = (int)x;
cout << x << ' ' << y << endl;
return 0;
}
五、顺序语句例题
5.1 输出第二个整数:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a, b, c;
cin >> a >> b >> c;
cout << b << endl;
return 0;
}
5.2 计算 (a + b) * c的值
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a, b, c;
cin >> a >> b >> c;
cout << (a + b) * c << endl;
return 0;
}
5.3 带余除法
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
int c = a / b, d = a % b;
cout << c << ' ' << d << endl;
return 0;
}
5.4 求反三位数:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cin >> n;
int a = n % 10;
n = n / 10;
int b = n % 10;
n = n / 10;
int c = n;
cout << a << b << c << endl;
return 0;
}
5.5 交换两个整数
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 3, b = 4;
int t = a;
a = b;
b = t;
cout << a << ' ' << b << endl;
return 0;
}
5.6 输出菱形
#include <iostream>
#include <string>
using namespace std;
int main()
{
char c;
cin >> c;
cout << " " << c << endl;
cout << " " << c << c << c << endl;
cout << c << c << c << c << c << endl;
cout << " " << c << c << c << endl;
cout << " " << c << endl;
return 0;
}