文章目录
目录
一、int型
%md:可以使 不足m位的int型变量 进行 右补齐,其中高位用空格补齐,如果变量本身就超过了m位则不变
int x=123;
int y=123456;
printf("%4d\n",x);
printf("%d\n",y);
输出:
123
123456
int x=123;
int y=123456;
printf("%04d\n",x);
printf("%d\n",y);
输出:
0123
123456
二、浮点型
1 控制小数点位数(超过6位)—“%.7f”
1.1 例题: 求圆的面积,要求输出结果保留7位小数
#include<iostream>
#include<iomanip>//setiosflags的头文件
#include<cmath>
using namespace std;
int main()
{
int r;
double ans;
double PI=atan(1.0)*4;//求出精确的圆周率π
cin>>r;
ans=PI*r*r;//圆的面积
cout<<setiosflags(ios::fixed)<<setprecision(7)<<ans<<endl;
return 0;
}
上面那个格式很难一下记住,发现一个不麻烦的写法:
atan(1) * 4后,printf (" %.7f ",ans);
#include<bits/stdc++.h>
using namespace std;
int main()
{
double PI=atan(1)*4;
int r;
cin>>r;
double ans;
ans=PI*r*r;
printf("%.7f",ans);
}
2 控制小数点位数(不超过6位)—“A=%.4lf”
2.1 例题:已给定π=3.14159,求圆的面积,要求输出结果保留4位小数
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
double r;
cin >> r;
printf("A=%.4lf",3.14159*r*r);
}
3 浮点数比较大小(易出bug)
浮点数比较大小,由于精度问题,所以直接比较有时可能会出错
在比较的时候需要用一个很小的数值来进行比较。
(二分法的思想)当二者之差小于这个很小的数时,就认为二者是相等的了
由于浮点类型double保留6位小数,所以用1e-6来控制
判断大于的时候,就是 if ( a > b && fabs( a - b ) > 1e-6 )
判断小于的时候,就是 if ( a < b && fabs( a - b )> 1e-6 )
#include<cstdio>
#include<cmath>
const double flag = 1e-6;
int main()
{
double a,b;
scanf("%lf %lf",&a,&b);
if(fabs(a - b) <= flag)
printf("ok\n");
else
printf("no\n");
return 0;
}
double x=12.34567
printf("%.3lf", x); //保留3位小数,四舍五入
输出:
12.346
三、字符
1 cin与gets()
cin不接受空格,而 gets() 则接受空格
2 getline
2.1 注意
如果在使用getline()之前有使用scanf()那么需要用getchar()将前面的换行符读取,再使用getline()
2.2 getline (cin,s);可读取空格
getline()这个函数是可以读取空格,遇到换行符或者EOF结束,但是不读取换行符的
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string name;
cout << "Please, enter your full name: ";
getline (cin,name);
cout << "Hello, " << name << "!\n";
return 0;
}
输出结果1:
输出结果2:
例题:三国语言
已知,菲律宾人在说话时,一定会在最后加上 po,日本人在说话时,一定会在最后加上 desu 或 masu,韩国人在说话时,一定会在最后加上mnida。
现在,有 n 个外国人,每个人都来自菲律宾或日本或韩国,他们每个人都说了一句话,请你根据他们说的话来判断他们具体是哪国人。
输入格式
第一行包含整数 n,表示外国人的数量。
接下来 n 行,每行包含一个字符串,表示其中一人说的一句话。
输入保证字符串中只包含小写字母和下划线,并且一定以上述四个后缀之一结尾。
输出格式
共 n 行,第 i 行输出第 i 个外国人是哪国人。
菲律宾人表示为 FILIPINO,日本人表示为 JAPANESE,韩国人表示为 KOREAN。
数据范围
前三个测试点满足 1≤n≤10。 所有测试点满足 1≤n≤30,每个输入字符串长度范围 [1,1000]。
输入样例:
8
kamusta_po
genki_desu
ohayou_gozaimasu
annyeong_hashimnida
hajime_no_ippo
bensamu_no_sentou_houhou_ga_okama_kenpo
ang_halaman_doon_ay_sarisari_singkamasu
si_roy_mustang_ay_namamasu
输出样例:
FILIPINO
JAPANESE
JAPANESE
KOREAN
FILIPINO
FILIPINO
JAPANESE
JAPANESE
代码:
#include<iostream>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
string s;
int n;
while(n--)
{
getline(cin,s);
int len=s.length();
if(s[len-1]=='o')
cout<<"FILIPINO"<<endl;
else if(s[len-1]=='u')
cout<<"JAPANESE"<<endl;
else if(s[len-1]=='a')
cout<<"KOREAN"<<endl;
}
return 0;
}
2.3 getline (cin,s,‘#’);
以#作为结束符时,#以及#后面的字符就不再读取
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string name;
cout << "Please, enter your full name: ";
getline (cin,name,'#');
cout << "Hello, " << name << "!\n";
return 0;
}
输出结果:
2.4cin.getline()
cin.getline()是将字符串存储在字符数组当中,也可以读取空格,也可以自己设置结束符标志
#include <iostream>
using namespace std;
int main ()
{
char name[256], title[256];
cout << "请输入你的名字: ";
cin.getline (name,256);//在不遇到结束符的情况下,最多可接收256-1=255个字符到name中
cout << "请输入你最喜欢的水果: ";
cin.getline (title,256);
cout << name << "最喜欢的水果是: " << title;
return 0;
}
输出结果:
2.5 while(getline(cin,line))
while(getline(cin,str))
{
cout<<str<<endl;
}
注意这里默认回车符停止读入,按Ctrl+Z或键入EOF回车即可退出循环。
在这个语句中,首先getline从标准输入设备上读入字符,然后返回给输入流cin,
注意了,是cin,所以while判断语句的真实判断对象是cin,也就是判断当前是否存在有效的输入流
2.6 getline(cin,str) 与 cin.getline(str)
cin.getline()函数是处理数组字符串的,其原型为cin.getline(char * , int),第一个参数为一个char指针,第二个参数为数组字符串长度。
getline(cin,str)函数是处理string类的函数。第二个参数为string类型的变量。
#include<iostream>
#include<string>
using namespace std;
int main()
{
char s[20];
string str;
cin.getline(s,20);
getline(cin,str);
cout<<s<<endl;
cout<<str<<endl;
}
2.7 例题:反转单词
问题描述
伊格纳修斯喜欢以相反的方式写词。
给定由Ignatius编写的单行文本,您应该 反转所有 单词 然后输出它们。
输入
输入包含几个测试用例。 输入的第一行是单个整数T,它是测试用例的数量。 T测试案例如下。
每个测试用例占一行包含多个单词。
一行中最多可包含1000个字符。
产量
对于每个测试用例,您应输出已处理的文本。
样本输入
3
olleh !dlrow
m’I morf .udh
I ekil .mca
样本输出
hello world!
I’m from hdu.
I like acm.
#include<iostream>
#include<string>
using namespace std;
int main()
{
int T;
while (cin>>T)
{
getchar(); //吸收T带来的回车换行
for (int i = 0; i < T; i++)
{
string str;
getline(cin, str);
int end = 0,top = 0;
while (str[end] != '\0') //没有遍历到最后一个单词
{
if (str[end]==' ') //遇到了空格
{
//倒序输出
for (int i = end-1; i >=top; i--)
{
cout << str[i];
}
cout << str[end];
top = end + 1;
}
end++;
}
if (str[end]=='\0') //遍历到了最后一个单词
{
//直接倒序输出最后一个单词
for (int i = end-1; i >=top-1; i--)
{
cout << str[i];
}
}
cout << endl;
}
}
}
3 string 与char
3.1 头文件
#include //char
#include //string
4 求参数长度不用strlen,用s.size()
1、string 定义的字符串求长度用s.size(),
先定义一个字符串s,遍历时用 (int i=1; i<=s.size(); i++) 就可以
2、char 定义的字符数组用strlen(s)
4.1 char类型 求长度用strlen(s)
注意输入用gets()
#include<iostream>
//写成#include<string>的话,strlen函数会报错
#include<cstring>//strlen函数头文件,是C语言库中的函数,注意不要写成string
using namespace std;
int main()
{
char s[110];
gets(s); //不能用cin
cout<<strlen(s)<<endl;//输出字符串长度
for(int i=0;i<strlen(s);i++)//逐个输出字符串中的字符
cout<<s[i]<<endl;
return 0;
}
4.2 string类型 求长度用s,size()
注意输入用cin
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cin>>s;//不能用gets
cout<<s.size()<<endl;//输出字符串的长度
for(int i=0;i<s.size();i++)//逐个输出字符串中的字符
cout<<s[i]<<endl;
return 0;
}
5 sizeof和strlen的区别:
sizeof ( ) 用来计算 参数所占的空间字节大小
strlen ( ) 用于 计算字符串的长度,是一种函数,必须为char,不能是string
6字符串的输入中有空格
6.1 用法:istringstream可以创建一个字符串流对象来继承某个字符串的内容
并将其中通过空格分离的字符单独提取出来
6.2 头文件 sstream
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
int main()
{
string s ;
while(getline(cin,s))
{
istringstream ss(s);//创建istringstream对象ss
string word;//创建接收字符串word
while(ss>>word)//一次将ss中每个字符输入到word中
{
cout<<word<<endl;
}
}
return 0;
}
效果:
四、结构体
1 日期结构体的写法
日期结构体
struct Date
{
int year;
int month;
int day;
}a[1000];
例:日期排序
注意:日期结构体 和 比较函数cmp 的写法
1.1 例题:比较日期年月日的日期大小,并按照顺序输出
#include<iostream>
#include<algorithm>
using namespace std;
//日期结构体
struct Date
{
int year;
int month;
int day;
}a[1000];
//比较日期A与日期B函数
//注意输入格式 用const struct Date &A
//int cmp(const struct Date &A,const struct Date &B)
int cmp(Date A,Date B)
{
if(A.year!=B.year)
return A.year<B.year;
else if(A.month!=B.month)
return A.month<B.month;
else
return A.day<B.day;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d/%d/%d",&a[i].month,&a[i].day,&a[i].year);
}
sort(a,a+n,cmp);
for(int i=0;i<n;i++)
{
//输出补足前导0
printf("%02d/%02d/%04d\n",a[i].month,a[i].day,a[i].year);
//cout<<a[i].year<<"/"<<a[i].month<<"/"<<a[i].day<<cout<<endl;
}
return 0;
}
五、进制转换:
1 由N进制转化为十进制:strtol 函数
1.1 头文件:#include < stdlib.h >
1.2 函数原型:long int strtol (const char *str, char **endptr, int base)
1.3 用法:
1、参数base的范围为2~36,和0
2、由base进制转化为十进制
3、strtol检测到第一个非法字符时,立即停止检测,
4、其后的所有字符都会被当作非法字符处理
5、合法字符串会被转换为long int, 作为函数的返回值。
6、非法字符串,即从第一个非法字符的地址,被赋给endptr。即endptr为非法字符串
1.4 例题:
写出一个程序,输入一个十六进制的数值字符串,输出该数值的十进制字符串。
输入格式
输入包含多组测试数据。
每组数据占一行,包含一个十六进制的数值字符串。
输出格式
每组数据输出一行结果,表示给定数值的十进制字符串。
数据范围
每个输入最多包含 100 组数据。
所有答案均在 int 范围内。
输入样例:
0xA
输出样例:
10
#include<stdlib.h> //strtol函数头文件
using namespace std;
char s[1000];
char *stop;
//char *stop=0;
int main ()
{
while (cin >> s)
printf("%d\n", strtol(s, &stop, 16));
return 0;
}
1.5 代码:
1、二进制转化为十进制
二进制中,10为合法字符,转化为十进制:2
而非法字符stop为: 379cend$3
#include<iostream>
#include<stdlib.h> //strtol函数头文件
using namespace std;
int main()
{
char buffer[20]="10379cend$3";
char *stop;
printf("%d\n",strtol(buffer, &stop, 2)); //输出2
cout << stop << endl; //输出379cend$3
return 0;
}
2、十进制转化为十进制
十进制中,10379为合法字符,cend$3
#include<iostream>
#include<stdlib.h> //strtol函数头文件
using namespace std;
int main()
{
char buffer[20]="10379cend$3";
char *stop;
printf("%d\n",strtol(buffer, &stop, 10)); //输出10379
cout << stop << endl; //输出cend$3
return 0;
}
3、16进制转化为十进制
10379ce为十六金枝槐中的合法字符,nd$3为非法字符
#include<iostream>
#include<stdlib.h> //strtol函数头文件
using namespace std;
int main()
{
char buffer[20]="10379cend$3";
char *stop;
printf("%d\n",strtol(buffer, &stop, 16)); //输出17005006
cout << stop << endl; //输出nd$3
return 0;
}
4、判断十进制数是否合法
#include<iostream>
#include<stdlib.h> //strtol函数头文件
using namespace std;
int main()
{
const char *ch = "5500";
char *endptr = 0;
// const char *ch1 = "";
// if (*ch1 == 0)
// cout << true << endl;
cout<<strtol(ch, &endptr, 10)<<endl;
cout << endptr << endl; //此处endptr = "",因为5500后为空,没有非法字符串
if (*endptr == 0) //endptr = "", 所以*endptr = 0
cout << "true" << endl;
return 0;
}
六、多组输入:
多组输入,输入为0 0 时表示输入的结束
注意:有个逗号
while( scanf ( "%d%d", &a, &b ) , (a || b ))
七、取整
1 向上取整
1.1 整型
写法1
int result = (n - 1)/k + 1;
写法2
int result = (n + k - 1)/k;
1.2 浮点型(函数ceil)
1、用函数ceil:ceil(x)返回的是大于x的最小整数
2、原型:double ceil(doube x);
3、返回值:返回一个double类型的数,此数默认有6位小数
4、如果需要保留m位小数,输出时用%.mlf控制
#include <stdio.h>
#include <math.h>
int main()
{
double i = ceil(2.45);
double j = ceil(-2.45);
printf("%f\n%f\n",i,j);
}
//输出结果为:3.000000 -2.000000
2 向下取整
2.1整型
用 / 直接除,自动向下取整
2.2 浮点型 (函数 floor)
注意 : i、j定义为double
取整前的数据,定义成什么类型,取整后的数据也要定义成一样的类型
#include <stdio.h>
#include <math.h>
int main()
{
double i = floor(2.45);
double j = floor(-2.45);
printf("%f\n%f\n",i,j);
}
//输出结果为:2.000000 -3.000000
八、四舍五入(round函数)
C99标准支持roud()函数
#include <stdio.h>
#include <math.h>
int main()
{
double i = round(2.45);
double j = round(-2.45);
printf("%f\n%f\n",i,j);
}
//输出结果为:2.000000 -2.000000
如果不支持roud函数,自定义一个四舍五入函数:
#include <stdio.h>
#include <math.h>
int Rounding(double x)
{
return x>0 ? (int)(x+0.5) : (int)(x-0.5);
}
int main()
{
double i = Rounding(2.45);
double j = Rounding(-2.45);
printf("%f\n%f\n",i,j);
}
//输出结果为:2.000000 -2.000000
九、奇偶判断
1、对2整除
注意:
1、写成 if( i % 2 == 1 ) 来判断奇数是错误的,
因为要考虑num为负数情况,余数也为负数-1,而写成!=0,则无论num正负数都可以
2、仅当被除数为负时,余数才为负数,与除数的正负无关
3、即:-5%10== -5;-5%(-10)== -5
// odd 奇数
if(num % 2 != 0) cout<<"odd"<<endl;
// even 偶数
if(num % 2 == 0) cout<<"even"<<endl;
2、位运算
因为1的二进制数是0000 0001,奇数的二进制数的最后一位都是必定是1,所以num & 1一定是1,
而偶数的二进制数最后一位一定0,num & 1必定是0。
注意:写的时候,判断偶数 不能写成 if ( num&1 != 1 ),
要将num&1用括号括起来, 要写成 if ( (num & 1) != 1 )
// odd 奇数
if((num & 1) == 1) cout<<"odd"<<endl;
// even 偶数
if((num & 1) != 1) cout<<"even"<<endl;