2023/10/13 - C-3_双目运算符-单目运算符-输出限定宽度-%占位符的基本用法-scanf的基本用法
#include<stdio.h>
// C_3
// 1 运算符 ,属于双目运算符( 具有两个操作数 )
// + - * / % .....
//int main()
//{
// // / 除号符 计算 用于整数与小数计算 商
// //printf("%d\n", 7 / 2);// 当除号两边都是整数时 进行的是整数除法,得到的也是 整数
// //printf("%f\n", 7 / 2);// 进行的是整数除法 但是输出的格式却是小数 会造成bug 输出全 0,错误写法
//
// // 当除号两边 任意一个是 小数,则进行的是 小数除法
// //printf("%lf\n", 7 / 2.0);// 3.500000 小数默认跟 6位小数,默认补 0;
// //printf("%d\n", 7 / 2.0);// 同理 错误写法 ,输出 0
//
// 限定 小数位数
// //printf("%.1f\n", 24 / 2.0);// 限定小数位输出 12.0
//
// // % :取模符号,用于计算 余数,,!! 注意!! % 只能用于计算整数 不可以是小数
// //printf("%d\n", 7 % 2);// 输出占位符是 %d
//
// // + - * 与数学无大多差异,,唯一需要注意的是! 在编程里是要注意 符号优先级的问题!!!!!!!!!!!
//
//
// return 0;
//}
2 变量初始化 与 赋值操作
//int main()
//{
// //int A;// 创建变量但是不进行变量初始化,叫做未初始化变量,注意!!虽然我们没有进行 初始化但是 系统是帮我们放了一个随机值的 (是一个很小的负数)
// 注意! 这是一个不推荐的写法 ,凡是在创建变量时都建议赋值一个初始值,不然如果直接使用或打印 在某些代码中可能会出现不可预料的结果
// printf("%d\n", A);// vs 编译器直接报错,不允许使用未初始化的 变量
// 还有一种是 计数器
// //int count;
// //for (int i = 0; i < 10; i++)
// //{
// // count++;// VS编译不过去 但是其他编译器 还是有可能编译过的,但是 结果会是 出乎意料的,
// //}
//
// //int a = 0;// 这个在创建变量的同时进行赋予初始值 叫做 初始化
// //a = 1;// 在创建变量后 再进行赋值 就叫做 赋值操作
//
//
// C 支持连续赋值操作,(不推荐,影响代码阅读体验)
// //int a = 1;
// //int b = 1;
// //int c = 0;
// //c = b = a = a + 1;// 连续赋值操作 从右向左 依次进行赋值操作
// //! a=a+1;
// //! b=a;
// //! c=b;
// // 不便于阅读
//
//
// // 复合赋值操作 (推荐),简单明了
// int a = 1;
// int b = 1;
// a += 1;
// //a=a+1;
//
// b -= 1;
// // b=b-1;
// // 凡是运算符 都是可以写成 复合赋值的
//
//
// return 0;
//}
//
// 3 单目运算符 ++ -- +(正) -(负)
//int main()
//{
// //int a = 0;
// //int b = 0;
// //b = a++;// 后置++ 先使用再自增
// //b = ++a;// 前置++ 先自增再使用
// // -- 同理
// // 注意!!! ++ 和 -- 是具有副作用的,会永久性的改变原值,(相当于赋了一次值),所以在不需要改变原值的情况下,先把值赋给其他变量再进行使用
//
// // + -
// // 正常创建的数前面都是拥有一个隐藏的 +
// int a = 1;// 等同于 +1
// //但是 - ,是真真切切的变为负值
// a = -1;
// a = +-1;//两者意义相同,+是默认 - 添加就会改变
// // 数学中的 负负的正的情况 不可以直接写为 -- ,而是在变量的基础上加一个 -
// int b = -a;
// //printf("%d\n", b);// 1
// //printf("%d\n", -a);// 1
//
// //printf("%d\n", --a);// -2 ,因为 -- 被编译器解析成 --
//
// // 在输出的数前面打印 + -
// a = 1;
// printf("%+d\n", a);// -1 如果输出是负数 那么 + 无意义
// printf("%-d\n", -a);// 注意! 只有在变量是 负数时才会进行 负数打印 ,如果是正数,那么 - 也将无意义
//
// // printf 返回值 是输出的 字符 的个数 size_t
// printf("%d", printf("%d", printf("%d", 43))); //43 2 1,,,如果加了空格隔开 也算一个字符哦
//
// return 0;
//}
4 占位符
//int main()
//{
// // printf :f -- format ,格式输出 % 表示的是占位符,后面跟的是 所占位的 类型,%d 就代表的是 所占位的是一个 int 类型的位置
//
// // 输出时限定 所占位的宽度
// //printf("%d\n", 123);//正常输出
// //printf("%05d\n", 123);// %5d 表示读取 5个整数,如果不足5位 拿空格填充,正数默认的是右对齐 所以在打印时看见的是 前面空格再是打印的数字
// //printf("%0*d\n",5, 123);// 宽度代替符号
//
// //printf("%-5d\n", 123); // 负数表示的 左对齐,就可以看见 123_ _ ,先输出再打印空白格
//
// // 小数的 宽度
// // 小数的宽度中 小数点也是算作一个宽度的 写法 是 n.n ,前者 n 表示的是 总宽度,后者 n 表示的是 小数的位数
// //printf("%05.1f\n", 7.0 / 2);// 003.5
// //printf("%05.2f\n", 7.0 / 2);// 03.50 小数为主,整数部分根据小数部分发生变化
//
// printf("%0*.*f\n",5,2, 7.0 / 2);// 宽度与小数位 替代符号 *
//
// return 0;
//}
// 5 scanf 函数
//int main()
//{
// // printf 与 scanf都是库函数
// // printf 是输出函数 而 scanf 是输入函数
// // scanf 格式化输入基本与 printf 相同
//
// //int a = 0;
// //scanf("%d", &a);// 输入时 改变的是变量的右值 所以需要取地址()
// 注意! 这里直接使用scanf函数 VS会报错的,VS会认为scanf是安全的函数,取消报错需要在 源文件的 行首位置添加报错的那段话
//
// 不安全是因为 在特定的输入时不会进行空间检查 造成bug
// //char a1[3] = { 0 }; // 数组名就是地址,代表的是数组首元素的起始地址,,但是如果指定在数组的的指定下标内输入的话 依旧需要取地址
// //scanf("%s", a1);// 如果输入的字符超过3, 会直接报空间越界的情况,因为会一直读字符 ,直到读取结束或者不属于字符类型的元素才会停止,(没有不属于字符的元素吗)
//
//
// // scanf 返回值,是成功读取的个数,如果读取错误返回的是 EOF(-1)
// //int b = 0;
// //int c;
// //int a = scanf("%d%d", &b, &c);//想要直接阻止 输入 需要按 3次 Ctrl+z键,按一次 回车按一次
// //printf("%d\n", a);// 可以看见 正常读取与异常读取时的 返回结果
//
// // %[0~9] 在此集合内读取
//
// // scanf 函数的特性 在读取数字时 会自动跳过 空白字符 制表符 以及换行符
// // 会在读取的第一个非空白字符起读取 然后在下一个空白字符处结束,或者是 不符合读取要求结束
//
// //int a = 0;
// //int b = 0;
// //int c = 0;
// 当输入 123# 0 时的结果
// //scanf("%d", &a);
// //printf("%d\n", a);//123
// //scanf("%d", &b); //因为 # 不符合读取要求所以直接就结束了
// //printf("%d\n", b);// 0
// //scanf("%d", &c);
// //printf("%d\n", c);// 0
//
//
// // 但是 %c 就不是这样的了,我们知道 计算机里的所有一切都是有一个个的字符组合而成 ,所以,如果不处理好%c的读取的结果,就会造成读取混乱
// // 当我们在键盘上输入时 不会直接输入到我们指定的变量中 而是需要经过一个区域 叫做缓冲区 ,我们输入的都放在缓冲区里,需要我们按个回车键 才会进行读取然后放到我们的变量里
//
// // 后期会有非常多的错误发生在 输入字符上面,因为回车键也是字符,同样会被输入到 缓冲区里等待,
// // 所以这里需要借用scanf的特性 ,在首次读取时会跳过所有的空白字符 直到遇到遇到第一个不是空白的字符然后进行读取,直到读取到下一个空白字符结束 或者整个结束
// // scanf 在读取字符串上还有一个特性,那就是 不会进行空白字符的读取(首个空白字符不算),导致这一缺点,无法进行 一个 字符串语句的读取
// // 所以 C 拥有一个函数 gets 弥补这个缺点
//
// // %C 是不具有 跳过空白字符的特性的(首个也不可以)
// //char a = 0;
// //char b = 0;
// 所以会发现 啥都看不见
// ///*scanf("%c", &a);
// //printf("%c\n", a);
// //scanf("%c", &b);
// //printf("%c\n", b);*/
//
// 解决方法就是 在%c 前面+一个空白字符 ,告诉编译器 跳过空白字符
// 就可以看见想要打印的字符了
// //scanf(" %c", &a);
// //printf("%c\n", a);
// //scanf(" %c", &b);
// //printf("%c\n", b);
//
// // 为了尽量避免 VS上的scanf存在危险,所以 规定了 限定读取字符个数来尽量避免bug
// //char a[4] = { 0 };
// //scanf("%3s", a);// 需要注意的是 限定的读取个数 必须比 数组大小少一位 不然依旧错误哦
// //printf("%s\n", a);
//
// // scanf函数中 在里面输入什么 我们在输入时就要怎么输入,不然就会读取错误
// // 所以 避免这一规定性 C的scanf 也拥有可代替的输入格式,
// // 这一输入格式 称为 赋值忽略符 %*c
// // 意义是:只负责读取,读取之后直接丢掉
//
// //int year = 0;
// //int month = 0;
// //int day = 0;
// //scanf("%d%*c%d%*c%d", &year, &month, &day);//注意 输入的 符号依旧的是 英文的
// //printf("%d %d %d\n", year, month, day);
//
// // 最后 scanf 在输入时 \n 这个东西前面不要乱加 !!!!!!!!!!!!!!!!!!!!!!!
//
//
// return 0;
//}