数据和C
scanf
和 getchar()
都是 C 语言中用于输入的函数,它们之间存在一些相同点和区别。
相同点
- 数据来源:两者都从标准输入(通常是键盘)读取数据。
- 缓冲区:输入的数据首先被放入输入缓冲区,然后这两个函数从缓冲区中读取数据。
- 用途:都可用于从用户那里获取输入数据。
区别
scanf | getchar() | |
---|---|---|
功能 | 格式化输入函数,根据指定的格式字符串从输入流中读取数据,并将其存储在指定的变量中。 | 字符输入函数,从输入流中读取下一个可用的字符(包括空格、制表符和换行符,但通常用于读取单个字符)。 |
返回值 | 成功读取并转换的输入项的数量,如果读取失败或到达文件末尾,则返回 EOF(通常是 -1)。 | 读取的字符的 ASCII 码值,如果到达文件末尾或发生读错误,则返回 EOF(通常是 -1)。 |
输入格式 | 需要指定格式字符串,该字符串定义了输入数据的类型和格式。 | 不需要指定格式字符串,直接读取下一个字符。 |
读取方式 | 可以读取多种类型的数据(如整数、浮点数、字符串等),并根据格式字符串进行转换。 | 每次只能读取一个字符,包括空格、制表符和换行符(尽管通常用于读取非空白字符)。 |
空白字符处理 | 在读取过程中会跳过空白字符(空格、制表符、换行符),直到遇到非空白字符为止。 | 不会跳过空白字符,包括空格、制表符和换行符(除非在特定情况下,如紧跟在 scanf 调用后读取换行符)。 |
缓冲区处理 | 读取后,缓冲区中可能残留未处理的字符(如换行符),这可能会影响后续的输入操作。 | 读取后,缓冲区中该字符之后的字符仍然保留,等待后续的输入操作。 |
使用场景 | 适用于需要按照特定格式读取多个数据项的情况。 | 适用于需要逐个字符读取输入的情况,或者当 scanf 由于格式不匹配而无法正确读取时,可以使用 getchar() 来读取剩余的输入。 |
示例
以scanf为例:
#include <stdio.h>
int main() {
int num;
float value;
printf("Enter an integer and a float: ");
scanf("%d %f", &num, &value);
printf("You entered: %d and %.2f\n", num, value);
return 0;
}
以getchar()为例
#include <stdio.h>
int main() {
int c;
printf("请输入一个字符: ");
c = getchar();
printf("你输入的字符是: %c\n", c);
return 0;
}
平时大多使用的是scanf,关于getchar()了解的较少,所有也查阅了部分资料
在C语言中,getchar()
函数是一个标准输入输出库(stdio.h)中的函数,用于从标准输入(通常是键盘)读取下一个可用的字符(不包括空白字符,如空格、制表符或换行符,除非在特定模式下,如通过 scanf("%c", &c);
时可能会读取到这些字符)。getchar()
函数读取字符并将其作为 int
类型返回,这是因为在某些情况下,函数需要返回一个特殊的错误指示符(EOF,即文件结束符,其值通常为-1)来指示读取操作失败或已到达文件末尾。
基本用法
#include <stdio.h>
int main() {
int c;
printf("请输入一个字符: ");
c = getchar(); // 读取一个字符
printf("你输入的字符是: %c\n", c);
return 0;
}
在这个例子中,程序会等待用户输入一个字符,并打印出该字符。注意,虽然getchar()
返回的是int
类型,但在这里我们直接将其赋值给了一个int
类型的变量c
,并在打印时将其视为char
类型(通过%c
格式说明符)。
读取多个字符
如果你想连续读取多个字符,可以在循环中使用getchar()
。
#include <stdio.h>
int main() {
int c;
printf("请输入字符(输入'q'退出): ");
while ((c = getchar()) != 'q' && c != EOF) {
putchar(c); // 将读取的字符输出到标准输出
}
if (c == EOF) {
printf("\n读取结束(EOF)\n");
} else {
printf("\n退出。\n");
}
return 0;
}
在这个例子中,程序会不断读取用户输入的字符,直到输入'q'或遇到EOF(在Windows上,这通常是Ctrl+Z然后回车;在Unix/Linux/macOS上,通常是Ctrl+D)。
注意事项
getchar()
函数读取的是下一个可用的字符,包括缓冲区中的字符(如果有的话)。因此,在连续调用getchar()
时,它可能会读取之前遗留在缓冲区中的字符。- 在读取输入时,如果输入的是多字符行,并且你只期望读取一个字符,那么该行中后续的字符(包括换行符)将留在输入缓冲区中,可能会对后续的输入操作产生影响。
- 可以通过清空输入缓冲区(例如,使用循环读取并丢弃直到遇到换行符的字符)来避免上述问题。但请注意,这通常不是处理输入的最佳方式,因为它依赖于特定平台的换行符行为(在Windows上是
\r\n
,在Unix/Linux/macOS上是\n
)。
数据类型关键字
char可以表示较小的数字,float,double,long double都表示带小数点的数。_Bool类型表示布尔值(ture或者false),_Complex和_Imaginary分别表示复数和虚数。
char可以表示较小的数字:
char
类型在 C 和 C++ 等编程语言中主要用于表示单个字符。然而,从底层实现的角度来看,char
实际上是以整数(通常是 8 位,即 1 字节)的形式存储的,这意味着它也可以用来表示较小的整数。
具体来说,char
类型可以表示的值范围取决于它是有符号的还是无符号的:
-
有符号
char
(signed char
): 在大多数系统上,它可以表示的值范围是从 -128 到 127(包括两端)。这是因为有符号的整数使用最高位(bit)作为符号位(0 表示正数,1 表示负数),剩下的 7 位用于表示数值的大小。 -
无符号
char
(unsigned char
): 它可以表示的值范围是从 0 到 255。因为没有符号位,所有的 8 位都用于表示数值的大小。
尽管 char
主要用于字符表示,但在需要存储小的整数值时,使用 char
(尤其是 unsigned char
)可以节省内存空间。不过,需要注意的是,在使用 char
类型表示整数时要特别注意其有符号性,因为不同的处理可能会导致意外的结果(比如,在有符号 char
和无符号 char
之间进行运算时)。
示例代码:
#include <stdio.h>
int main() {
signed char sc = -1; // 有符号 char
unsigned char uc = 255; // 无符号 char
printf("Signed char: %d\n", sc);
printf("Unsigned char: %u\n", uc);
// 尝试将字符类型用于数值计算
signed char sc_add = sc + 1; // 结果取决于系统如何处理溢出
unsigned char uc_sub = uc - 1; // 结果为 254
printf("Signed char + 1: %d\n", sc_add);
printf("Unsigned char - 1: %u\n", uc_sub);
return 0;
}
从C99标准开始,<stdbool.h>
头文件被引入,它定义了 _Bool
类型作为布尔类型,以及两个宏 true
和 false
来分别表示布尔值真和假。
但是,需要注意的是,_Bool
关键字在C语言编程中并不常见,因为 <stdbool.h>
头文件更常通过 bool
关键字来被使用,bool
是 _Bool
的别名,并且 true
和 false
宏也被定义。因此,在C99及之后的C标准中,推荐使用 bool
、true
和 false
而不是 _Bool
、1
和 0
(尽管后者在技术上也是有效的,但不够清晰)。
示例代码(C99及之后):
#include <stdio.h>
#include <stdbool.h>
int main() {
bool flag = true; // 使用 bool 类型和 true 宏
if (flag) {
printf("Flag is true.\n");
} else {
printf("Flag is false.\n");
}
flag = false; // 设置为 false
if (!flag) {
printf("Now flag is false.\n");
}
return 0;
}
这个例子中,bool
类型被用来声明一个布尔变量 flag
,它可以使用 true
或 false
来赋值。同时,if
语句通过检查 flag
的值来决定执行哪个分支。
尽管 _Bool
是C99标准中定义的布尔类型,但在实际编程中,推荐使用 bool
、true
和 false
,因为它们更直观、更易于理解。
整数和浮点数
整数
顾名思义就是没有小数,像3.1,3.000都不属于整数
关于二进制转化成十进制:
例如:
0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
0*2^7 | 0*2^6 | 0*2^5 | 0*2^4 | 0*2^3 | 1*2^2 | 1*2^1 | 1*2^0 |
0 | 0 | 0 | 0 | 0 | 4 | 2 | 1 |
综上:所得出的结果为七
浮点数
概念和整数差不多,关键要理解两者的存储方式不相同
浮点型的存储方式分成小数和指数部分,例如:整数7和7.0两者在数值上相同,但是,7.0写成0.7E1,0.7为小数,1为指数。