c++ day3(一)


在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<climits>

int main()
{
    using namespace std;
    short n_short = SHRT_MAX;
    int n_int = INT_MAX;
    long n_long = LONG_MAX;
    long long n_llong = LONG_LONG_MAX;

    cout << "length in Bytes: \n";
    cout << "short: " << sizeof(n_short) << endl;
    cout << "int: " << sizeof(n_int) << endl;
    cout << "long: " << sizeof(n_long) << endl;
    cout << "long long: " << sizeof(n_llong) << endl;

    cout << endl << "Maximum values: \n";
    cout << "short: " << n_short << endl;
    cout << "int: " << n_int << endl;
    cout << "long: " << n_long << endl;
    cout << "long long:" << n_llong << endl;

    cout << endl << "Minimum values: \n";
    cout << "short: " << SHRT_MIN << endl;
    cout << "int: " << INT_MIN << endl;
    cout << "long: " << LONG_MIN << endl;
    cout << "long long:" << LONG_LONG_MIN << endl;

    cout << endl << "bits per bytes: " << CHAR_BIT << endl;

    return 0;
}
length in Bytes:
short: 2
int: 4
long: 4
long long: 8

Maximum values:
short: 32767
int: 2147483647
long: 2147483647
long long:9223372036854775807

Minimum values:
short: -32768
int: -2147483648
long: -2147483648
long long:-9223372036854775808

bits per bytes: 8

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

原来#define并不是很受欢迎

大括号初始化器

可以用大括号初始化数组和结构,也可以用于初始化单值变量,这时候可以不加等号。虽然看起来很奇怪,但是这种大括号初始化是c++11新增的,可以用于初始化任何类型,而在此之前,c++ 中的不同类型要用不同方法初始化,非常麻烦

#include<iostream>
#include<climits>

int main()
{
    using namespace std;
    int num1 = {2};
    cout << num1 << endl;

    int num2{3};
    cout << num2 << endl;

    int num3{};
    cout << num3 << endl;

    int num4 = {};
    cout << num4 << endl;

    return 0;
}
2
3
0
0

整型表示范围(上溢,下溢)

这图不错,编程语言的类型的表示范围只是一个圈,一个闭环,不是一个数轴,所以你如果在重置点加1减1,得到的会是错误结果,其他地方都不会错
在这里插入图片描述

示例1

#include<iostream>
#include<climits>
#define ZERO 0
int main()
{
    using namespace std;

    short ss = SHRT_MAX;
    unsigned short mm = ss;
    cout << "ss has " << ss << " dollars. \n";
    cout << "mm has " << mm << " dollars. \n";
    cout << "Add $1 to each account. \n";
    ss++ ;
    mm++;
    cout << "Now ss has " << ss << " dollars. \n";
    cout << "Now mm has " << mm << " dollars. \n";
    cout << "poor ss!\n";
    cout << endl;

    ss = ZERO;
    mm = ss;
    cout << "ss has " << ss << " dollars. \n";
    cout << "mm has " << mm << " dollars. \n";
    cout << "Take $1 from each account. \n";
    ss-- ;
    mm--;
    cout << "Now ss has " << ss << " dollars. \n";
    cout << "Now mm has " << mm << " dollars. \n";
    cout << "lucky mm!";
}
ss has 32767 dollars.
mm has 32767 dollars.
Add $1 to each account.
Now ss has -32768 dollars.
Now mm has 32768 dollars.
poor ss!

ss has 0 dollars.
mm has 0 dollars.
Take $1 from each account.
Now ss has -1 dollars.
Now mm has 65535 dollars.
lucky mm!

因为short占16位,那么有符号short只有15位用于表示数值大小,2的15次方是32768,所以正数部分是0 000000000000001到0 111111111111111,即1到32767,而负数是1 111111111111111 到1 000000000000001,即-1到-32768(由补码求原码:符号位不变,其他所有位取反再加1)。

现在ss是0 11111111111111111111(32767),加1变为 1 000000000000000, 转为原码还是1 000000000000000 ,表示-32768
mm是0 11111111111111111111(32767),加1变为 1 000000000000000,由于第一位不是符号位,所以数值就是32768( 2 1 5 2^15 215

ss是0, 则为0 000000000000000, 减去1, 即加上-1(1 111111111111111),得1 111111111111111, 转为原码是1 000000000000001,即-1;
mm是0, 则为0 000000000000000, 减去1, 即加上-1(1 111111111111111),得1 111111111111111,但是最高位不是符号位,所以这就是 2 1 6 − 1 = 65535 2^16-1=65535 2161=65535

另一个很好展示上图那种圆圈的示例

// 整数溢出的示例
#include <stdio.h>
int main()
{
    int x = 2147483647; // 有符号int可以表示的最大值(32位)
    unsigned int y = 4294967295; // 无符号int可以表示的最大值(32位)
    printf("%d, %d, %d\n", x, x+1, x+2);
    // 无符号int用%d显示则被当做是有符号的,unsigned int y = 4294967295本来是32个1,结果最高位被当做符号位,成为-1
    printf("%d, %d, %d\n", y, y+1, y+2);
    printf("%u, %u, %u\n", y, y+1, y+2);
    return 0;
}
2147483647, -2147483648, -2147483647
-1, 0, 1
4294967295, 0, 1

补一个C语言的整数溢出导致无限循环示例

uint8_t无符号8位整型,i=0,i-1=255,所以永远不会退出循环

#include <inttypes.h>
#include <stdio.h>
#include <inttypes.h>
uint8_t i = 5;
uint32_t count = 0;

int main()
{
    while(i-->=0)
    {
        count ++;
        printf("the number of while count is : %u\r\n",count);
    }
    return 0;
}

16进制,8进制

在这里插入图片描述

#include<iostream>
#include<climits>


int main()
{
    using namespace std;

    int chest = 20; //十进制
    int waist = 0x30; // 十六进制
    int leg = 042; // 八进制
    cout << "chest: " << chest << " (20 in decimal.)\n";
    cout << "waist: " << waist << " (0x30 in hex.) \n";
    cout << "leg: " << leg << " (042 in octal.)\n";
    return 0;
}

在这里插入图片描述

chest: 20 (20 in decimal.)
waist: 48 (0x30 in hex.)
leg: 34 (042 in octal.)

也可以用控制符hex, oct改变基数

#include<iostream>
#include<climits>


int main()
{
    using namespace std;

    int chest = 20; //十进制
    int waist = 0x30; // 十六进制
    int leg = 042; // 八进制
    cout << "chest: " << chest << " (20 in decimal.)\n";
    cout << hex << "waist: " << waist << " (0x30 in hex.) \n";
    cout << oct << "leg: " << leg << " (042 in octal.)\n";
    return 0;
}
chest: 20 (20 in decimal.)
waist: 30 (0x30 in hex.)
leg: 42 (042 in octal.)

在这里插入图片描述

常量类型如何确定

只要不是超出范围或者有后缀说明,否则就存为int
在这里插入图片描述

char类型

在这里插入图片描述

#include<iostream>
#include<climits>
int main()
{
    using namespace std;

    char ch;
    cout << "enter a character. \n";
    cin >> ch; // cin把a转化为97存入内存
    cout << "thanks for the " << ch << " character. \n"; //cout把97读为a
    return 0;
}

在这里插入图片描述

enter a character.
a
thanks for the a character.

cin cout为我们完成了转换工作

c++对字符用单引号,对字符串用双引号

#include<iostream>
#include<climits>


int main()
{
    using namespace std;

    char ch = 'm';
    int in = ch;
    cout << "The ASCII code for " << ch << " is " << in << endl;
    ch ++;
    in = ch;
    cout << "The ASCII code for " << ch << " is " << in << endl;
    cout.put(ch);
    cout << '!';
    cout.put('!');
    return 0;
}
The ASCII code for m is 109
The ASCII code for n is 110
n!!

cout.put()是OOP第一个示例。点号是成员运算符,put()是成员函数,用它是历史原因,总之现在已经可以不通过它了,cout已经可以一人完成所有任务了。

牛逼!char用作数值类型竟然可能不确定有无符号,必须明确指定
在这里插入图片描述

转义字符

在这里插入图片描述

#include<iostream>
#include<climits>
int main()
{
    using namespace std;
    cout << '\a';
    cout << "I love \"you\".";
    return 0;
}

\a会响诶,Windows启动的声音

I love "you".

bool类型

在这里插入图片描述
c语言以前是没有bool类型的,后来C99标准引入了,引入头文件<stdbool.h>即可,详见这篇博文

#include<iostream>
int main()
{
    using namespace std;
    bool is_ready = true;
    int a = true;
    int b = false;
    bool c = -10;
    bool d = 0;
    cout << is_ready << endl;
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
    cout << d << endl;
    return 0;
}
1
1
0
1
0

可以看到,给bool类型的变量赋0以外的值都会被存为1,不会存储原值
用true和false给int等数值类型赋值,赋的是1和0

const

在这里插入图片描述在这里插入图片描述在这里插入图片描述

#include<iostream>
int main()
{
    using namespace std;
    const int MONTHS = 12;
    cout << MONTHS << endl;
    cout << sizeof MONTHS << endl;
    return 0;
}
12
4

浮点数

整数类型共有11种:
char
signed char, short, int , long, long long,
unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long
在这里插入图片描述

#include<iostream>
int main()
{
    using namespace std;
    float a = 5e12;
    double b = 5e22;
    long double c =5e202;
    cout << a << endl;
    cout << sizeof a << endl;
    cout << b << endl;
    cout << sizeof b << endl;
    cout << c << endl;
    cout << sizeof c << endl;
    return 0;
}
5e+012
4
5e+022
8
5e+202
12

可以看到我的系统中float占4字节,double8字节,long double12字节,如果把c替换为5e602,cout会显示为inf,大概是超出了指数最大位数,但是我没有在float.h或者cfloat文件中找到描述指数最大位数的语句,于是不清楚最大指数位数

float和double精度差异

ios_base::fixed和ios_base::floatfield是iostream头文件提供的常量
大概ios_base也是个名称空间??

#include<iostream>
int main()
{
    using namespace std;
    float a = 10.0/3.0;
    double b = 10.0/3.0;
    const float million = 1e6;
    cout.setf(ios_base::fixed, ios_base::floatfield);//使用定点表示法输出,默认只打印小数点后6位
    cout << a << endl;
    cout << b << endl;
    cout << a * million << endl;
    cout << b * million << endl;
    cout << b * million * 10000 << endl;
    return 0;
}
3.333333
3.333333
3333333.250000
3333333.333333
33333333333.333336

a, b初始化相同,刚开始cout显示6位小数,看不出区别,乘以100万后,再显示6位小数,就看出了区别,float从第8个有效位,即小数点后第一位就出错了;但是b的13位都是对的;但是第17位也开始出错了

suo以float正确了7位,double正确了16位

精度造成错误

#include<iostream>
int main()
{
    using namespace std;
    float a = 5.2e18;
    float b = a + 1.0f;
    cout.setf(ios_base::fixed, ios_base::floatfield);
    cout << a << endl;
    cout << b << endl;
    cout << a - b << endl;
    return 0;
}
5200000055834050560.000000
5200000055834050560.000000
0.000000

可以看到,float显示了前8位是对的,第9位就错了(但是后面实验表明实际上第8位并没被表示,只是巧合),而且b也没加上1,而是和a相等,这是因为a加1需要在小数点后18位加1,float根本没表示出来,当然不行啦

改a为float a = 5.2e6;

5200000.000000
5200001.000000
-1.000000

结果才对,说明float只能正确表示数字的前7位,从第8位开始就不行啦

通过这样的方式测试发现,double可以正确表示数字的前16位

#include<iostream>
int main()
{
    using namespace std;
    double a = 5.2e15;
    double b = a + 1.0f;
    cout.setf(ios_base::fixed, ios_base::floatfield);
    cout << a << endl;
    cout << b << endl;
    cout << a - b << endl;
    return 0;
}
5200000000000000.000000
5200000000000001.000000
-1.000000

long double 可以正确表示数字的前19位

#include<iostream>
int main()
{
    using namespace std;
    long double a = 5.2e18;
    long double b = a + 1.0f;
    cout.setf(ios_base::fixed, ios_base::floatfield);
    cout << a << endl;
    cout << b << endl;
    cout << a - b << endl;
    return 0;
}

5200000000000000000.000000
5200000000000000001.000000
-1.000000

在这里插入图片描述

小测试

在这里插入图片描述

用多种方式输出一个字符:

#include<iostream>
int main()
{
    using namespace std;
    char c = 88;
    cout << c << endl;
    cout << char(88) << endl; // c++风格强制转换,int to char
    cout << (char)88 << endl; // c语言风格
    cout.put(char(88));
    return 0;
}
X
X
X
X
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是用C语言编写的一个简单万年历程序: ```c #include <stdio.h> int days_of_month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char week[7][4] = {"日", "一", "二", "三", "四", "五", "六"}; int is_leap_year(int year) { return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); } int get_days_of_month(int year, int month) { if (month == 2 && is_leap_year(year)) { return 29; } else { return days_of_month[month]; } } int main() { int year, month; printf("请输入年份: "); scanf("%d", &year); printf("请输入月份: "); scanf("%d", &month); printf("====================\n"); printf(" %d 年 %d 月\n", year, month); printf("====================\n"); printf("日 一 二 三 四 五 六\n"); // 获得当月1号是星期几 int first_day_of_month = 1; for (int i = 1900; i < year; i++) { first_day_of_month += (is_leap_year(i) ? 366 : 365); } for (int i = 1; i < month; i++) { first_day_of_month += get_days_of_month(year, i); } first_day_of_month = first_day_of_month % 7; for (int i = 0; i < first_day_of_month; i++) { printf(" "); } // 输出当月所有天数 int days_of_current_month = get_days_of_month(year, month); for (int i = 1; i <= days_of_current_month; i++) { printf("%2d ", i); if ((first_day_of_month + i) % 7 == 0) { printf("\n"); } } if ((first_day_of_month + days_of_current_month) % 7 != 0) { printf("\n"); } printf("====================\n"); return 0; } ``` 此程序可以将输入的年份和月份作为参数,输出指定年月的日历,例如: ``` 请输入年份: 2022 请输入月份: 11 ==================== 2022 年 11 月 ==================== 日 一 二 三 四 五 六 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ==================== ``` ### 回答2: 编写一个万年历的C程序涉及到以下几个步骤: 1. 定义函数来判断某一年是否为闰年。闰年的判断规则是: - 如果该年份能被4整除但不能被100整除,则是闰年。 - 如果该年份能被400整除,则也是闰年。 2. 定义函数来计算某一年1月1日是星期几。我们可以利用Zeller公式来计算,该公式的逻辑是: - 根据公式: h = (q + [(13 * (m + 1)) / 5] + K + [K / 4] + [J / 4] - 2 * J) mod 7 - q 是日期,m 是月份(3代表3月,4代表4月,...,在公式中1月和2月被视为前一年的13月和14月),y 是年份的前两位数字,K 是年份的后两位数字,J 是年份的前两位数字。 - h 的值表示当年1月1日的星期几,0代表星期日,1代表星期一,以此类推。 3. 在主函数中,首先获取用户输入的年份,并使用闰年判断函数来确定该年份是否为闰年。然后使用星期计算函数来计算该年份的1月1日是星期几。 4. 根据1月1日的星期几,构建一个二维数组来表示整个年份的日历。数组的行表示星期,从0到6对应于星期日到星期六,列表示日期的排列。 - 我们可以使用循环来填充数组,首先填充1月,然后是2月,以此类推,直到12月。在填充的过程中,需要根据每个月的天数以及1月1日是星期几来确定日期的排列。 5. 最后,打印输出整个年份的万年历。 注意:以上步骤只是程序的基本框架,具体的实现细节还需根据个人的编程能力和经验来完善。 ### 回答3: 编写一个万年历的程序需要考虑到年、月、日的变化和计算规则。以C语言为例,可以使用基本的控制流和算术运算来实现。以下是一个简单的实现: ``` #include <stdio.h> int isLeapYear(int year) { if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { return 1; // 是闰年 } else { return 0; // 不是闰年 } } int main() { int month, year; printf("请输入年份:"); scanf("%d", &year); printf("请输入月份:"); scanf("%d", &month); int daysInMonth = 31; if (month == 2) { if (isLeapYear(year)) { daysInMonth = 29; } else { daysInMonth = 28; } } else if (month == 4 || month == 6 || month == 9 || month == 11) { daysInMonth = 30; } printf("\n------------------------\n"); printf(" %d年%d月\n", year, month); printf("------------------------\n"); printf("日 一 二 三 四 五 六\n"); int dayOfWeek = 0; // 0表示星期日 // 计算并打印每天的日期 for (int day = 1; day <= daysInMonth; day++) { if (day == 1) { // 根据1号是星期几,确定第一行空格的数量 for (int i = 0; i < dayOfWeek; i++) { printf(" "); } } printf("%2d ", day); // 每7天换行 if ((dayOfWeek + day) % 7 == 6) { printf("\n"); } dayOfWeek = (dayOfWeek + 1) % 7; } printf("\n------------------------\n"); return 0; } ``` 这个程序首先判断输入的年份是否为闰年,然后根据月份确定该月的天数。接着,使用一个循环打印出该月的日历,根据每个月的1号是星期几对齐打印内容。最后,根据每7天换行。这样可以得到一个简单的万年历。 注:以上代码只是一个范例,可能没有考虑一些特殊情况,如输入的年份和月份是否合法等。实际使用中可以根据自己的需求和补充完善相关功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值