C 语言是一种功能强大、灵活多变的编译型语言,广泛应用于系统编程、嵌入式开发等领域。运算与选择结构是 C 语言编程的基础,它们构成了程序逻辑的核心。
C 语言是一种编译型语言,从创建 C 程序到运行出最终结果,包括:编辑、编译、链接和运行四个过程。
int
、float
等。保留字 | 用途 |
---|---|
auto | 存储类说明符,用于声明自动变量(通常省略,因为默认就是auto) |
break | 跳转语句,用于跳出循环或switch语句 |
case | switch语句中的分支标签 |
char | 数据类型,用于声明字符类型的变量或数组 |
const | 类型修饰符,用于声明常量(只读变量) |
continue | 跳转语句,用于跳过循环中的剩余部分,直接进入下一次迭代 |
default | switch语句中的默认分支标签 |
do | 循环控制语句,用于构成do-while循环 |
double | 数据类型,用于声明双精度浮点类型的变量或数组 |
else | 条件语句的一部分,用于在if语句条件不满足时执行 |
enum | 枚举类型声明 |
extern | 存储类说明符,用于声明在其他文件中定义的变量或函数 |
float | 数据类型,用于声明单精度浮点类型的变量或数组 |
for | 循环控制语句,用于构成for循环 |
goto | 跳转语句,用于无条件跳转到程序中标记的位置 |
if | 条件语句,用于根据条件执行不同的代码块 |
inline | 函数说明符,用于建议编译器将函数内联扩展(在某些实现中可能忽略) |
int | 数据类型,用于声明整型变量或数组 |
long | 数据类型,用于声明长整型变量或数组(也可以与int组合为long int) |
register | 存储类说明符,用于建议编译器将变量存储在寄存器中(在某些实现中可能忽略) |
restrict | 类型修饰符,用于限制指针(C99引入) |
return | 函数返回语句,用于从函数返回一个值 |
short | 数据类型,用于声明短整型变量或数组(也可以与int组合为short int) |
signed | 类型修饰符,用于声明有符号类型的整数(默认情况) |
sizeof | 运算符,用于获取类型或变量的大小(以字节为单位) |
static | 存储类说明符,用于声明静态变量或函数 |
struct | 结构体类型声明 |
switch | 条件语句,用于根据表达式的值选择多个代码块中的一个来执行 |
typedef | 类型定义,用于为数据类型定义新的名称(别名) |
union | 联合类型声明 |
unsigned | 类型修饰符,用于声明无符号类型的整数 |
void | 数据类型,用于声明不返回值的函数或表示空类型(例如void*) |
volatile | 类型修饰符,用于声明可能会被意外修改的变量 |
while | 循环控制语句,用于构成while循环 |
_Bool | 数据类型,用于声明布尔类型的变量(C99引入,等价于bool,但为C++保留) |
_Complex | 数据类型,用于声明复数的变量(C99引入) |
_Imaginary | 数据类型,用于声明虚数的变量(C99引入) |
_Generic | 类型选择运算符(C11引入) |
_Noreturn | 函数说明符,用于声明不返回的函数(C11引入) |
_Static_assert | 静态断言(C11引入) |
_Thread_local | 存储类说明符,用于声明线程局部存储的变量(C11引入) |
注意:
_Bool
、_Complex
、_Imaginary
、_Generic
、_Noreturn
、_Static_assert
和_Thread_local
这些保留字在C90标准中并不存在,是C99或C11标准中引入的。这个列表应该涵盖了C语言标准中的所有保留字。然而,不同的编译器可能会引入额外的保留字或关键字,所以在使用特定编译器时,最好查阅其文档以获取完整的信息。
int sum;
比int a;
更易于理解。int SumofStudent;
不同于int sumofstudent;
。int
作为变量名。printf
作为变量名。month
5xy
(以数字开头),int
(保留字),your name
(包含空格)int
、double
等。机器会根据数据类型为变量分配相应的地址和空间。#define PI 3.14
定义了一个符号常量PI
。#include "stdio.h"
#define PI 3.14
void main() {
double r, circum, area; // 定义3个双精度变量
r = 1.0;
circum = 2 * PI * r; // 计算圆的周长
area = PI * r * r; // 计算圆的面积
printf("circum=%f, area=%f\n", circum, area);
}
说明:
#define PI 3.14
是符号常量的定义,属于编译预处理命令。void main()
是主函数的定义,程序从这里开始执行。double r, circum, area;
定义了三个双精度变量。C 程序由若干个函数构成,现阶段涉及的程序只包含 main()函数;
函数由语句序列构成,语句完成具体的操作。
语句按其作用和形式分为:
示例代码:
#include <stdio.h>
int main() {
double a, b, x;
// 输入a和b的值
printf("请输入一元一次方程的系数a和常数项b(用空格分隔): ");
scanf("%lf %lf", &a, &b);
// 检查a是否为零,避免除以零的错误
if (a == 0) {
printf("输入错误,a不能为0,否则为非法一元一次方程。\n");
}
} else {
// 计算x的值
x = -b / a;
// 输出结果
printf("方程的解是: x = %.2lf\n", x);
}
return 0;
}
#include <stdio.h>
#include <math.h>
int main() {
double a, b, c, x1, x2, Delta;
// 输入部分
printf("请输入一元二次方程ax^2+bx+c=0的三个系数:\n");
printf("请输入系数 a = \t");
scanf("%lf", &a);
printf("请输入系数 b = \t");
scanf("%lf", &b);
printf("请输入系数 c = \t");
scanf("%lf", &c);
Delta = b * b - 4 * a * c;
printf("a=%.2f,\nb=%.2f,\nc=%.2f\n", a, b, c);
if (fabs(a) > 1e-9) // 即a!=0,使用一个小数来避免浮点数比较的问题
{
if (Delta < 0)
{
printf("方程有没有实根!\n");
}
else if (Delta == 0)
{
x1 = x2 = -b / (2 * a);
printf("方程有两个相等的根:\nx1 = x2 = %.2f\n", x1);
}
else
{
x1 = (-b + sqrt(Delta)) / (2 * a);
x2 = (-b - sqrt(Delta)) / (2 * a);
printf("方程的两个实根分别为\nx1 = %.2f,\nx2 = %.2f\n", x1, x2);
}
}
else if (fabs(b) > 1e-9) // 即b!= 0 ,使用小数来避免浮点数比较的问题
{
x1 = -c / b;
printf("方程是一元一次方程,x1 = -c/b = %.2f\n", x1);
}
else if (fabs(c) > 1e-9) // 即c!= 0 ,使用小数来避免浮点数比较的问题
{
printf("方程无解,因为0 * x^2 + 0 * x+%.2f=0不成立。\n", c);
}
else
{
printf("x可以是任意值,因为方程是0=0。\n");
}
return 0;
}
+
、-
、*
、/
、%
,用于执行基本的数学运算。注意,整数除法结果向下取整,如 5/2
结果为 2
。类型 | 运算符 | 运算符号的含义 | 实例 |
---|---|---|---|
算术运算 | +、-、、/ | 用于整数、浮点类型, | ax-b/2-3 | ||
% | 求余数 | A=5; B=A%2; | |
++、-- | 变量自身 +1,或变量自身-1 | i++; j--; |
数学 | C 语言 | 运算 | 优先级 | 运算限制条件 |
---|---|---|---|---|
++ | 后置自增 | 1 | 单目、右结合、各类型的变量 | |
-- | 后置自减 | 1 | 单目、右结合、各类型的变量 | |
- | - | 取负数 | 1 | 单目、右结合、各类型的表达式 |
× | * | 乘 | 2 | 双目、左结合、各类型的表达式 |
÷ | / | 除 | 2 | 双目、左结合、各类型的表达式。两个整型数相除,结果为整型,小数被截断。 |
% | 取余数 | 2 | 双目、左结合、整型及字符型,结果为整型 | |
+ | + | 加 | 3 | 双目、左结合、各类型的表达式 |
- | - | 减 | 3 | 双目、左结合、各类型的表达式 |
=
、<=
、==
、!=
,用于比较两个操作数的值,返回布尔值(真或假)。运算符 | 运算符号的含义 | 实例 |
---|---|---|
>、>=、<、<= | 比较 2 个变量的大小,结果为 1(真)或 0(假) | score<=60 |
==、!= | 两个变量是否相等?比较 | 注意:实数比较相等的问题 |
&&
(逻辑与)、||
(逻辑或)、!
(逻辑非),用于执行逻辑运算。逻辑运算符具有短路特性,即当逻辑表达式的值已经确定时,不会继续计算未涉及的操作数。类型 | 运算符 | 运算符号的含义 | 实例 |
---|---|---|---|
逻辑与运算 | && | 逻辑与运算同为1(真)结果才为 1(真) | d>=5 && d<=10 |
逻辑或运算 | | | | 逻辑或运算一个为1(真)结果为 1(真) | |
逻辑非运算 | ! | 逻辑非运算非1(真)为0(假),非0(假)为1(真) | |
逻辑向量 | &、|、^、 | 按位进行:与、或、异或 |
a | b | a&&b | a | b | !a | |
---|---|---|---|---|---|---|
0(假) | 0(假) | 0(假) | 0(假) | 1(真) | ||
0(假) | 1(真) | 0(假) | 1(真) | 1(真) | ||
1(真) | 0(假) | 0(假) | 1(真) | 0(假) | ||
1(真) | 1(真) | 1(真) | 1(真) | 0(假) |
&
或 ∧
True AND True = True
True AND False = False
False AND True = False
False AND False = False
|
或 ∨
True OR True = True
True OR False = True
False OR True = True
False OR False = False
¬
或 !
NOT True = False
NOT False = True
^
或 ⊕
True XOR True = False
True XOR False = True
False XOR True = True
False XOR False = False
⊙
或 ≡
(在一些文献中,XNOR 也可以表示为 !XOR
或 XOR NOT
)True XNOR True = True
True XNOR False = False
False XNOR True = False
False XNOR False = True
这些逻辑运算在计算机科学、电子工程和数学等领域有着广泛的应用。例如,在计算机编程中,它们用于控制结构(如条件语句和循环)、数据验证和位操作等。在数字电路中,它们通过逻辑门(如 AND 门、OR 门、NOT 门等)实现,以构建复杂的电路系统。
逻辑运算也遵循一定的运算规律。
例如:
结合律(Associativity):
x | ( y | z ) = ( x | y ) | z ,以及 x & ( y & z ) = ( x & y ) & z
交换律(Commutativity):
x | y = y | x ,以及 x & y = y & x
分配律(Distributivity):
x & ( y | z ) = ( x & y ) | ( x & z )
恒等律(Identity):
x | 0 = x ,x & 1 = x
归零律(Annihilator):
x & 0= 0
第四个(异或)定义是多余的,可以用前三个定义,推导出来,例如:
进一步,与、或、非是否可以归纳为两个运算呢?
例如,或运算可以归纳为非和与两种运算,
逻辑计算中只需要两个符号,(非、与),或(非、或),这是逻辑运算的最小体系
为了证明在逻辑计算中只需要两个运算符(例如“非”和“与”,或者“非”和“或”)就能完成所有逻辑运算,我们需要展示如何使用这两个运算符来模拟其他逻辑运算符(如“或”、“异或”等)。
不能只用一个运算符来完成所有逻辑运算。原因是逻辑运算包括基本的真值表操作,如与、或、非,它们各自具有不同的真值表输出。没有足够的信息(即只有一个运算符)来区分这些不同的操作。例如,“非”运算只能反转一个值的真假,而“与”和“或”则涉及两个值的组合。因此,至少需要两个运算符来模拟所有基本的逻辑运算。
=
,以及复合赋值运算符如 +=
、-=
、*=
、/=
、%=
等。赋值表达式: 变量 = 表达式赋值运算符左边(称为左值)必须是指向内存单元的变量(或指针),不能是常量或值表达式;赋值运算符右边(称为右值)是合法的 C 语言表达式。图示
例如: | |
---|---|
sum=sum+a | 合法 |
i++=5_i、a+b=c_4 | 非法 |
‘y’=x、x+1=y*a+3 | 非法 |
// C 语言中进制的书面表达
#include <stdio.h>
int main()
{
int x = 0101;//八进制(octal literal--用0开头)
int y=5; //十进制(直接写)
int w = 0x10; //十六进制(Hexdciaml---用0x开头)
int z = 0b010;//而进制(Binary---用0b开头)
printf("八进制的0101 = 十进制的: %d\n", x);
printf("八进制的0101+十进制5 = 十进制的:%d\n", y+x);
printf("十六进制0x10 = 十进制的:%d\n", w);
printf("二进制0b010 = 十进制的:%d\n", z);
printf("按16进制格式打印(八进制0101): %X\n", x);
return 0;
}
复合赋值运算符:
如:+=
,-=
,*=
,/=
,%=
,<<=
,>>=
,&=
,∧=
,|=
变量 op= 表达式
等价于:变量 = 变量 op (表达式)
a += b+3
等价于:a = a+(b+3)
<<
(左移)、>>
(右移)、&
(按位与)、|
(按位或)、^
(按位异或)、~
(按位取反),直接对整型数的二进制位进行操作。运算效率更高:例如,加密/解密运算符 | 操作 | 示例(设 a=0x36,b=0xb3) |
---|---|---|
~ | 按位取反 | a : 00110110,~a : 11001001 |
<<、>> | 左移、右移 | a <<2 : 11011000,a>>3 : 00000110 |
& | 按位与 | a & b : 00110110 & 10110011=00110010 |
^ | 按位异或 | a ^ b : 00110110 ^ 10110011=10000101 |
| | 按位或 | a| b : 00110110 | 10110011=10110111 |
&=、^=、 | =、<<=、>>= | 按位复合赋值运算 |
int a=-100,b;
b=a>>2;
printf(“a=%d,b=%d\n”,a,b);
位运算的用途
()
具有最高优先级,用于改变运算顺序。,
优先级最低,用于连接两个表达式,并返回最后一个表达式的值。优先级 | 运算符 | 名称 | 含义 | 说明 | 结合性 | 示例 |
---|---|---|---|---|---|---|
1 | () | 圆括号 | 用于改变运算顺序或函数调用 | 括号内的表达式会优先计算 | 左 | (a + b) * c ,printf("%d", a) |
2 | [] | 下标运算符 | 用于访问数组元素或指针指向的值 | 表达式[索引]表示访问索引处的元素 | 左 | arr[i] ,ptr[j] |
2 | -> | 结构体指针成员访问 | 用于通过结构体指针访问成员 | 指针-> 成员表示访问指针所指向的结构体中的成员 | 左 | ptr->member |
2 | . | 结构体成员访问 | 用于通过结构体变量访问成员 | 结构体.成员表示访问结构体中的成员 | 左 | structVar.member |
3 | ++ | 自增运算符 | 使变量的值增加 1 | 可以作为前缀或后缀使用 | 右 | ++a (前缀),a++ (后缀) |
3 | -- | 自减运算符 | 使变量的值减少 1 | 可以作为前缀或后缀使用 | 右 | --b (前缀),b-- (后缀) |
3 | ! | 逻辑非运算符 | 对布尔值取反 | 如果操作数为真,结果为假;如果操作数为假,结果为真 | 右 | !flag (如果 flag 为真,则结果为假) |
3 | ~ | 位非运算符 | 对整数的每一位取反 | 0 变为 1,1 变为 0 | 右 | ~num (对 num 的每一位取反) |
3 | sizeof | 大小运算符 | 返回类型或变量所占的字节数 | 在编译时计算,结果类型为 size_t | 右 | sizeof(int) ,sizeof(var) |
... | ... | ... | ... | ... | ... | ... |
6 | * | 乘法运算符 | 计算两个数的乘积 | 适用于整数和浮点数 | 左 | a * b (计算 a 和 b 的乘积) |
6 | / | 除法运算符 | 计算两个数的商 | 适用于整数和浮点数,整数除法结果向下取整 | 左 | c / d (计算 c 除以 d 的商) |
6 | % | 求余运算符 | 计算两个数相除的余数 | 仅适用于整数 | 左 | e % f (计算 e 除以 f 的余数) |
7 | + | 加法运算符 | 计算两个数的和 | 适用于整数、浮点数和字符(ASCII 码值相加) | 左 | g + h (计算 g 和 h 的和) |
7 | - | 减法运算符 | 计算两个数的差 | 适用于整数、浮点数和指针(地址差) | 左 | i - j (计算 i 和 j 的差) |
8 | << | 左移运算符 | 将二进制位向左移动指定的位数 | 右侧用 0 填充,可用于乘以 2 的幂 | 左 | k << l (将 k 的二进制位向左移动 l 位) |
8 | >> | 右移运算符 | 将二进制位向右移动指定的位数 | 对于无符号数,左侧用 0 填充;对于有符号数,可能用符号位填充 | 左 | m >> n (将 m 的二进制位向右移动 n 位) |
9 | < | 小于运算符 | 比较两个数的大小 | 如果左侧小于右侧,结果为真 | 左 | o < p (如果 o 小于 p,则结果为真) |
9 | <= | 小于等于运算符 | 比较两个数的大小 | 如果左侧小于或等于右侧,结果为真 | 左 | q <= r (如果 q 小于或等于 r,则结果为真) |
9 | > | 大于运算符 | 比较两个数的大小 | 如果左侧大于右侧,结果为真 | 左 | s > t (如果 s 大于 t,则结果为真) |
9 | >= | 大于等于运算符 | 比较两个数的大小 | 如果左侧大于或等于右侧,结果为真 | 左 | u >= v (如果 u 大于或等于 v,则结果为真) |
10 | == | 等于运算符 | 比较两个数是否相等 | 如果两个数相等,结果为真 | 左 | w == x (如果 w 等于 x,则结果为真) |
10 | != | 不等于运算符 | 比较两个数是否不相等 | 如果两个数不相等,结果为真 | 左 | y != z (如果 y 不等于 z,则结果为真) |
11 | & | 位与运算符 | 对两个数的每一位进行与运算 | 只有当两个对应的位都为 1 时,结果位才为 1 | 左 | a & b (对 a 和 b 的每一位进行与运算) |
12 | ^ | 位异或运算符 | 对两个数的每一位进行异或运算 | 当两个对应的位不同时,结果位为 1 | 左 | c ^ d (对 c 和 d 的每一位进行异或运算) |
13 | | | 位或运算符 | 对两个数的每一位进行或运算 | 只要有一个对应的位为 1,结果位就为 1 | 左 | `e |
14 | && | 逻辑与运算符 | 对两个布尔值进行与运算 | 只有当两个操作数都为真时,结果才为真 | 左 | g && h (如果 g 和 h 都为真,则结果为真) |
15 | || | 逻辑或运算符 | 对两个布尔值进行或运算 | 只要有一个操作数为真,结果就为真 | 左 | `i |
16 | ? : | 三元运算符 | 根据条件选择两个值中的一个 | 条件 ? 值 1 : 值 2,如果条件为真,结果为值 1,否则为值 2 | 右 | k > 0 ? "Positive" : "Negative" (如果 k 大于 0,则结果为"Positive",否则为"Negative") |
17 | = | 赋值运算符 | 将右侧的值赋给左侧的变量 | 右侧表达式的值会存储在左侧变量中 | 右 | a = b (将 b 的值赋给 a) |
... | ...= | 复合赋值运算符 | 结合算术或位运算符进行赋值 | 例如 a += b 等同于 a = a + b | 右 | c += d (等同于 c = c + d) |
类型 | 描述 | 典型大小(字节) | 取值范围(示例) |
---|---|---|---|
char | 字符类型,用于存储单个字符 | 1 | -27~27-1; -128 到 127 或 0 到 255(取决于编译器) |
signed char | 有符号字符类型,与char 通常相同,但显式表示有符号 | 1 | -27~27-1; -128 到 127 |
unsigned char | 无符号字符类型 | 1 | 0~28-1; 0 到 255 |
short | 短整型 | 2 | -215~215-1; -32,768 到 32,767 |
unsigned short | 无符号短整型 | 2 | 0~216-1; 0 到 65,535(无符号) |
int | 整型(通常与short 或 long 相同,具体取决于编译器和平台) | 4 | -231~231-1; -2,147,483,648 到 2,147,483,647 |
unsigned int | 无符号整型 | 4 | 0~232-1; 0 到 4,294,967,295(无符号) |
long | 长整型(通常按 4 字节) | 4 或 8(64 位系统通常为 8) | -231~231-1 或 -263~263-1; -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long | 无符号长整型 | 4 或 8 | 0~232-1 或 0~264-1; 0 到 18,446,744,073,709,551,615(无符号) |
long long | 更长的整型(C99 标准引入) | 8 | -263~263-1; -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long long | 无符号更长的整型 | 8 | 0~264-1; 0 到 18,446,744,073,709,551,615(无符号) |
float | 单精度浮点型 | 4 | 3.4E±38F(6-7 个有效数字)$ -3.4 \times 10^{-38} \sim 3.4 \times 10^{38} $ |
double | 双精度浮点型 | 8 | 1.7E±308(15 个有效数字)$ -1.7 \times 10^{-308} \sim 1.7 \times 10^{308} $ |
long double | 扩展精度浮点型(具体精度取决于编译器和平台) | 8、12 或 16 | 3.4E±4932L(18-19 个有效数字,具体取决于实现)$ -1.7 \times 10^{-308} \sim 1.7 \times 10^{308} $ |
转义序列 | 意义 | ASCII码 | 示例输出 |
---|---|---|---|
\a | 报警(Alert) | 7 | 发出蜂鸣声(取决于终端) |
\b | 退格(Backspace) | 8 | 将光标向左移动一个位置 |
\f | 换页(Form Feed) | 12 | 将光标移动到下一页(取决于终端或打印机) |
\n | 换行(Newline) | 10 | 将光标移动到下一行的开头 |
\r | 回车(Carriage Return) | 13 | 将光标移动到当前行的开头 |
\t | 水平制表符(Tab) | 9 | 将光标向右移动一定数量的位置(通常是8个空格) |
\v | 垂直制表符(Vertical Tab) | 11 | 将光标向下移动一定数量的位置(取决于终端) |
\\ | 反斜杠(Backslash) | 92 | 输出一个反斜杠字符 |
\' | 单引号(Single Quote) | 39 | 输出一个单引号字符 |
\" | 双引号(Double Quote) | 34 | 输出一个双引号字符 |
\? | 问号(Question Mark) | 63 | 输出一个问号字符(在现代C中通常不需要转义) |
\0 | 空字符(Null Character) | 0 | 字符串结束符,不输出任何字符 |
\ddd | 八进制字符 | - | 输出对应的ASCII字符(ddd为三位八进制数)'\101'代表'A' |
\xhh | 十六进制字符 | - | 输出对应的ASCII字符(hh为两位十六进制数)'\x41'代表'A' |
注意:
\ddd
和 \xhh
中的 d
和 h
分别代表八进制和十六进制数字,它们可以是0-7和0-9, a-f, A-F之间的字符。在实际使用时,需要替换为具体的数字。?
)通常不需要转义,但在某些旧版本的编译器或特定上下文中,可能需要使用 \?
来避免歧义。\0
)在C语言中用于表示字符串的结束,它不输出任何字符,但在内存中占用一个字节的空间,其ASCII码值为0。(目标类型) 变量或表达式;
示例:
int a = 5;
float b = (float)a; // 将int类型变量a强制转换为float类型,赋值给float类型变量b
示例:
int a = 5;
double b = a; // 自动将int类型变量a转换为double类型,赋值给double类型变量b
C 语言提供了丰富的数据类型,以支持各种编程需求。了解每种数据类型的特性和大小,以及掌握数据类型之间的转换规则,对于编写高效、健壮的 C 程序至关重要。
char
和 short
通常会被提升为 int
),字符型数据在运算时会被视为整型数据。float
类型在运算中会被提升为 double
类型。long double
参与,则所有其他浮点类型会被提升为 long double
。输入输出点原理
printf()
和 scanf()
实现数据的输入输出。#include <stdio.h> // 标准输入输出函数头文件
#include <math.h> // 数学函数头文件常用数学计算库函数:
printf
和 scanf
函数使用格式字符来指定数据的显示和输入格式。以下是一个关于常用格式字符的表格,包括它们的宽度和精度修饰符。格式字符 | 含义 | 示例 |
---|---|---|
%d | 十进制整数 | printf("%d", 42); |
%ld | 十进制整数长整型 long | printf("%ld", 42); |
%lld | 十进制整数长整型 long long | printf("%lld", 42); |
%u | 无符号十进制整数 | printf("%u", 42U); |
%x | 无符号十六进制整数(小写) | printf("%x", 2A); |
%X | 无符号十六进制整数(大写) | printf("%X", 2A); |
%o | 无符号八进制整数 | printf("%o", 52); |
%f | 浮点数(单精度实数 float) | printf("%f", 3.14159); |
%lf | 浮点数(双精度实数 double) | printf("%lf", 3.14159); |
%e | 浮点数(科学计数法) | printf("%e", 3.14159); |
%E | 浮点数(科学计数法,大写 E) | printf("%E", 3.14159); |
%g | 浮点数(根据数值自动选择) | printf("%g", 3.14159); |
%G | 浮点数(根据数值自动选择,大写 E) | printf("%G", 3.14159); |
%c | 单个字符 | printf("%c", 'A'); |
%s | 字符串 | printf("%s", "Hello"); |
%p | 指针地址(十六进制) | printf("%p", &var); |
%% | 百分号字符 | printf("%%"); |
希望这个表格能帮助你更好地理解和使用 C 语言中的格式化输入输出。
修饰符 | 意义 |
---|---|
%md | 以宽度 m 输出整型数,不足 m 位数时左侧补以空格。 |
%0md | 以宽度 m 输出整型数,不足 m 位数时左侧补以 0(零)。 |
%-md | 以宽度 m 左对齐输出整型数,不足 m 位数时右侧补以空格 |
%m.nlf | 以宽度 m 输出实型数,小数位数为 n 位。 |
%ms | 以宽度 m 输出字符串,不足 m 位数时左侧补以空格。 |
*
来指定。
printf("%5d", 42);
// 输出 " 42"(前面填充空格)*
时,可以通过一个额外的 int
参数指定宽度:printf("%*d", 5, 42);
// 同样输出 " 42".
和一个数字来指定。
printf("%.2f", 3.14159);
// 输出 "3.14"printf("%.*s", 3, "Hello");
// 输出 "Hel"(最多 3 个字符)printf()
printf()
函数用于向输出设备(如显示器)输出数据,可以使用格式控制符指定输出格式。
%d
格式符:以十进制的形式输出带符号整数 int#include<stdio.h>
int main()
{
int a=-10;
double b=3.5;
char c='A';
printf("%d,%d,%d,%d,%d\n",10,a,c,3.5,b);
}
运行结果:
%d 格式输出字符型即输出其 ASCII 值
%d 格式输出实数型会出现错误。
* `%d`**格式符:以十进制的形式输出带符号整数 int**
#include<stdio.h>
int main()
{
long long a1=9999999999;
printf("%d,%ld,%lld",a1,a1,a1);
}
运行结果:
超出数据类型范围则出现“溢出”
%ld:用来输出 long 类型
%lld:用来输出 long long 类型
* `%f`**格式符:以小数形式输出单精度实数 float**
#include<stdio.h>
int main()
{
float a1=1;
double a2=1;
printf("%f,%f,%f\n",a1/3,-3.78,2.345e2);
printf("%lf,%lf,%lf\n",a2/3,-3.78,2.345e2);
}
运行结果:
%lf:用来输出 double 类型
%f 和 %lf 默认输出 6 位小数。
* `%f`**格式符:以小数形式输出单精度实数 float**
#include<stdio.h>
int main()
{
float b1=3333333333.3333333;
double b2=3333333333.3333333;
printf("%f\n%lf\n",b1,b2);
}
运行结果:
float 有效位 7 位
double 有效位 15 位
%c
格式符:输出单个字符#include<stdio.h>
int main()
{
char c='0';
printf("%d,%c",c,c);
}
运行结果:
字符型按 %d 输出即输出其 ASCII 码值
scanf()
scanf()
函数用于从输入设备(如键盘)读取数据,并将其存储在指定的变量中。注意,scanf()
函数在读取字符或字符串时,需要特别注意缓冲区溢出和输入格式的问题。#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d%d%d",a,b,c);
// scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d",a,b,c);
}
// 程序编译没有问题,但执行会出现闪退,为什么?
// scanf函数中忘记&
&a 表达,是把输入的数存放到变量 a 地址代表的存储空间中
#include<stdio.h>
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%d,%d,%d",a,b,c);
}
1.使用空格作为分隔
2.使用回车符作为分隔
例如:
int num;
scanf("%d", &num); // 正确用法
这里 %d 表示程序期待一个整数输入。用户只需输入数字即可,无需考虑其他字符。
如果格式字符串中包含非格式字符,则用户输入时也必须包括这些字符。
例如:
int num;
scanf("Number: %d", &num); // 错误示例
在这种情况下,程序实际上等待用户键入 Number:
后跟一个整数。如果用户仅仅输入了数字,那么这次 scanf 调用可能不会成功读取数据。
注意事项使用 scanf 时尽量避免在格式字符串中加入额外的文字,因为这可能会导致输入处理上的困难。
#include<stdio.h>
int main()
{
int a;
char b;
double c;
scanf("%d%c%lf",&a,&b,&c);
printf("a=%d,b=%c,c=%lf\n",a,b,c);
}
输入:123 A 4.5
输出:a=123,b= ,c=0.000000
输入:123A4.5
输出:a=123,b=A,c=4.500000
在 C 语言中使用 scanf 函数进行输入时,空格、制表符和回车(换行)通常被视为分隔符。这意味着当你使用 %c 格式说明符来读取单个字符时,这些空白字符会被当作有效输入处理。不过,scanf 的行为依赖于具体的格式字符串和输入方式。例子
char ch;
scanf("%c", &ch);
假设用户直接按下回车键,程序将把回车符(\n
)存储到变量 ch
中。
char ch;
scanf(" %c", &ch); // 注意前面有一个空格
这里开头的空格告诉 scanf
忽略任何数量的空白字符,然后读取下一个非空白字符。这样即使用户先按下了几个空格或者回车,接着输入了一个字符,该字符也会被正确读入。
注意事项
%c
来读取一个字符,那么它会读取下一个未被跳过的字符,包括空格、制表符或换行符。
%c
且不希望读入空白字符时,可以通过在 %c
之前添加额外的空白字符来实现。getchar()
函数逐字符读取,并手动过滤不需要的空白字符,或者使用 fgets()
读取整行输入后再进行处理。scanf
时。要引入string.h头文件。
putchar( ) 输出1个字符
puts( ) 输出1个字符串
getchar() 输入1个字符,并回显
getch() 输入1个字符,不回显(头文件conio.h)
gets() 输入1个字符串,按回车结束