CPU,操作系统位数与地址总线,数据总线
- 关于寻址空间
对于32位的windows操作系统,其逻辑地址编码采用的地址位数是32位的,那么操作系统所提供的逻辑地址寻址范围是4GB,而在intel x86架构下,采用的是内存映射技术(Memory-Mapped I/O, MMIO),也就说将4GB逻辑地址中一部分要划分出来与BIOS ROM、CPU寄存器、I/O设备这些部件的物理地址进行映射,那么逻辑地址中能够与内存条的物理地址进行映射的空间肯定没有4GB了,看下面这幅图就明白了:
- 1
- 对于64位的操作系统,其逻辑地址编码采用的地址位数是40位,能够最大支持1T的逻辑地址空间。考虑一种情况,假如CPU是64位的,地址总线位数是40位,操作系统也是64位的,逻辑地址编码采用的地址位数也是40位,内存条大小是64GB,那么是不是内存条的64GB全部都能被利用了呢?答案是不一定,因为这里面还要考虑一个因素就是内存控制器,内存控制器位于北桥之内(现在基本都是放在CPU里面了),内存控制器的实际连接内存的地址线决定了可以支持的内存容量,也就是说内存控制器与内存槽实际连接的地址线如果没有40位的话,是无法完全利用64GB的内存条的存储空间的。
引入EOF
如何打开?
什么是EOF?
EOF = 1, 表示程序运行异常,错误码只有一位,转换为字符则可读性增强,程序员更加容易判断程序出错
如何触发?
行首输入 Ctrl + Z, 连续输入三次即可退出
code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
while (scanf("%d", &i) != EOF) { /* while 实现循环,后面要有一个小括号 */
printf("i = %d\n", i);
}
return 0;
}
循环获取输入代码存在的问题及解决方案
- 成功读取指定数据类型的数据,scanf的返回值是1
- 若读取失败,那么返回值是0,仍然不等于负一;
- 读取失败指的是 scanf() 希望读取到数字,实际输入为字符;
- 那么程序就会陷入死循环,此时应该使用内存刷新代码;
- code1
```c
define _CRT_SECURE_NO_WARNINGS
include
include
int main() { int i, ret; / scanf()成功捕获输入后,其值为1 / while ((ret = scanf(“%d”, &i)) != EOF) { / while 实现循环,后面要有一个小括号 / printf(“i = %d\n”, i); } return 0; }
6. code2
```c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
//vs 2012 使用 fflush(stdin), vs2017 vs2019 使用rewind(stdin)
int i, ret;
/* scanf()成功捕获输入后,其值为1 */
while (rewind(stdin), (ret = scanf("%d", &i)) != EOF) { /* while 实现循环,后面要有一个小括号 */
printf("i = %d\n", i);
}
return 0;
}
为什么不能使用 rewind(stdin)?循环读取字符
原本我们输入多个字符,scanf会依次读取,回车后返回所有字符的转换;
若加入 rewind(stdin),则将清除 除了第一个字符以外的其他字符;
code1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
char c;
while (scanf("%c", &c) != EOF) {
if (c != "\n") {
printf("%c\n", c - 32); /* 小写转换为大写 */
}
else {
}
}
return 0;
}
code2
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
char c;
int ret;
while (rewind(stdin), (ret = scanf("%c", &c)) != EOF) {
if (c != "\n") {
printf("%c\n", c - 32); /* 小写转换为大写 */
}
else {
}
}
return 0;
}
scanf()获取混合输入
%d %f获取输入时都会主动忽视空格,而%c不会,因此会导致以下的错误:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, ret;
char c;
float f;
ret = scanf("%d%c%f", &i, &c, &f);
printf("i = %d c = %c f= %f", i, c, f);
return 0;
}
解决方案:在scanf()获取约束前,使用空格预先占用输入时键入的空格
code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, ret;
char c;
float f;
ret = scanf("%d %c%f", &i, &c, &f);
printf("i = %d c = %c f= %f", i, c, f);
return 0;
}
printf()的使用
code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("name = %s, age = %3d, sex = %c, score= %4.1f", "Caesar", 34, "m", 98.5);
return 0;
}