运算符与分支循环语句
上节总结:上节首先通过了解 C 语言的基本数据类型种类、变量和常量的声明和定义方式,初步了解如何使用变量和常量。其次通过了解整型、字符型、实型这三种数据类型进一步巩固变量的使用,在这中间还了解 sizeof
运算符的使用。最后介绍了计算机中存储数据的基本方式,如何进行进制转换,以及当数据溢出时会发生什么。
类型限定符
限定符 | 含义 |
---|---|
extern | 声明一个变量,此处 extern 声明的变量没有建立存储空间,表示此变量在别处定义,变量只有在定义后才会创建存储空间 |
const | 定义一个常量,常量的值不能修改 |
volatile | 防止编译器优化代码 |
register | 定义寄存器变量,提高效率。register 是建议型的指令,而不是命令型的指令,如果 CPU 有空闲寄存器,那么 register 就生效,如果没有空闲寄存器,那么 register 无效 |
字符串
字符串是内存中一段连续的 char
空间,以 '\0'
(数字0)结尾。字符串常量是由双引号括起来的字符序列,如 "china"
、"C program"
,"$12.5"
等都是合法的字符串常量。
字符串常量与字符常量是不相同的,如字符常量 a
和字符串常量 "a"
,字符常量只有字符 a
,而字符串常量由两个字符 a
和 \0
,所以两个不可能相等的。
#include <stdio.h>
int main()
{
//打印字符串,字符串的格式匹配符是 %s
char str[] = "Hello World!"; // 字符串一般都是使用字符数组保存,数组内容后续会有讲解
printf("str = %s\n", str);
return 0;
}
printf
函数和 putchar
函数
printf
函数
在 C 语言中输出的函数由很多,其中 printf
是格式化输出函数,可以根据格式化匹配符输出指定类型的数据,格式匹配字符如下:
格式匹配字符 | 对应的数据类型 | 含义 |
---|---|---|
%d | int | 接受整数值并将它表示为有符号的十进制整数 |
%hd | short int | 短整数 |
%hu | unsigned short | 无符号短整数 |
%o | unsigned int | 无符号8进制整数 |
%u | unsigned int | 无符号10进制整数 |
%x /%X | unsigned int | 无符号 16 进制整数,x 对应的是 abcdef,X 对应的是 ABCDEF |
%f | float | 单精度浮点数 |
%lf | double | 双精度浮点数 |
%e /%E | double | 科学计数法表示的数,此处 "e "的大小写代表在输出时用的 “e” 的大小写 |
%c | char | 字符型,可以把输入的数字按照 ASCII 码相应转换为对应的字符 |
%s | char * | 字符串,输出字符串中的字符直至字符串中的空字符(字符串以 '\0‘ 结尾,这个 '\0' 即空字符) |
%p | void * | 以 16 进制形式输出指针 |
%% | % | 输出一个百分号 |
除此之外,printf
还有一些附加格式,其基本形式为 %-0m.nf
:
字符 | 含义 |
---|---|
l | 附加在 d,u,x,o 前面,表示长整型 |
- | 左对齐,没有此符号则为右对齐 |
m | 数据的最小宽度 |
0 | 将输出的前面补上 0 直到占满指定列宽为止不可以搭配使用- |
m.n | 指域宽,即对应的输出项在输出设备上所占的字符数。n 指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定 n 时,隐含的精度为 n=6 位 |
#include <stdio.h>
int main()
{
int abc = 10;
printf("abc = '%6d'\n", abc);
printf("abc = '%-6d'\n", abc);
printf("abc = '%06d'\n", abc);
printf("abc = '%-06d'\n", abc);
double d = 12.3;
printf("d = \' %-10.3lf \'\n", d);
return 0;
}
putchar
函数
在输出一个字符时,使用格式化输出比较麻烦,还要指定格式匹配类型,使用 putchar
函数可以直接输出字符,一般返回的是字符对应的 ASCII 码值,该函数不能输出字符串。
#include <stdio.h>
int main()
{
int ch = 'a';
putchar(ch);
putchar('\n');
return 0;
}
scanf
函数和 getchar
函数
scanf
函数
C 语言中,如果想要从标准输入设备读取数据,可以使用 scanf
,用法基本上与 printf
相同,不同之处需要指定保存数据的地址空间,scanf
会将读取到的数据保存到地址空间中,如 scanf("%d", &num);
。
#include <stdio.h>
int main()
{
char ch;
int a;
char str[10];
printf("请输入 ch 的字符:");
scanf("%c", &ch);
printf("ch = %c\n", ch);
printf("请输入 a 的值:");
scanf("%d", &a);
printf("a = %d\n", a);
printf("请输入 str 的值:");
scanf("%s", str);
printf("str = %s\n");
return 0;
}
scanf
接收字符串具有安全隐患,如果字符数组的存储空间不足,则多余的数据不会存储在数组中,数组也没有 \0
作为结束标记。scanf
在读取字符串时,遇到空白字符,如空格、换行符以及制表符就会自动终止读取。
getchar
函数
在上面提到了 putchar
可以输出一个字符,而 getchar
则是标准输入中读取一个字符,读取的数据是字符的 ASCII 的形式。
#inlcude <stdio.h>
int main()
{
int ch = getchar();
putchar(ch);
putchar('\n');
return 0;
}
运算符与表达式
基本的运算符使用略。
类型转换
数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题。转换的方法有两种:
- 自动转换(隐式转换):遵循一定的规则,由编译系统自动完成
- 强制类型转换:把表达式的运算结果强制转换成所需的数据类型,基本语法为
(数据类型)(表达式);
类型转换的原则:占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低。
#include <stdio.h>
int main()
{
int num = 5;
printf("dv = %.2f\n", num/2.0); // 自动类型转换,int 转换成 float
float price = 3.6;
int weight = 4;
double sum = (int)(price * weight); // 强制转换
printf("价格:%lf\n", sum);
return 0;
}
程序流程
C语言支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
- 顺序结构:程序按顺序执行,不发生跳转。
- 选择结构:依据是否满足条件,有选择的执行相应功能。
- 循环结构:依据条件是否满足,循环多次执行某段代码。
选择结构
if
语句
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
if (a > b)
{
printf("%d\n", a);
}
return 0;
}
if...else
语句
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
if (a > b)
{
printf("%d\n", a);
}
else
{
printf("%d\n", b);
}
return 0;
}
if...else if...else
语句
#include <stdio.h>
int main()
{
unsigned int a;
scanf("%u", &a);
if (a < 10)
{
printf("个位\n");
}
else if (a < 100)
{
printf("十位\n");
}
else if (a < 1000)
{
printf("百位\n");
}
else
{
printf("很大\n");
}
return 0;
}
三目运算符
三目运算符也具有分支选择的作用,语法格式为 <表达式 1> ? <表达式 2> : <表达式 3>;
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = (a > b ? a : b);
printf("c = %d\n", c);
return 0;
}
switch
语句
switch
语句是一种精确匹配的分支结构,其根据某个变量的值来选择指定分支的语句执行,并且每条分支都会使用 break
作为结束,如果没有 break
,则会继续执行下一个分支。
#include <stdio.h>
int main()
{
int score;
scanf("%d", &score);
switch (score/10)
{
case 10:
case 9:
printf("优秀\n");
break;
case 8:
case 7:
printf("良好\n");
break;
case 6:
printf("及格\n");
break;
default:
printf("不及格\n");
break;
}
return 0;
}
循环结构
while
语句
#include <stdio.h>
int main()
{
int num = 1;
while (num <= 100) {
if ((num % 7 == 0) || (num % 10 == 7) || (num / 10 == 7))
{
printf("敲桌子\n");
}
else
{
printf("%d\n", num);
}
num++;
}
return 0;
}
do...while
语句
do...while
与 while
的区别是,do...while
会先执行一次循环体中的语句,再进行判断循环条件,而 while
则是先判断循环条件,在决定是否执行循环体语句。
#include <stdio.h>
int main()
{
int a, b, c;
int num = 100;
do {
a = num % 10; // 个位
b = num / 10 % 10; // 十位
c = num / 100; // 百位
if (a * a * a + b * b * b + c * c * c == num)
{
printf("%d 是水仙花数\n", num);
}
num++;
} while (num < 1000);
return 0;
}