C语言
常量
#define 常量名 常量值
#include <stdio.h>
#define PI 3.14 // 定义常量 PI,常量值 3.14
int main()
{
double area;
double r = 1.2;
area = PI * r * r;
printf("面积 : %.2f", area);
return 0;
}
const 数据类型 常量名 = 常量值;
#include <stdio.h>
const double PI = 3.14; // const 定义常量时,需要加分号
int main()
{
double area;
double r = 1.2;
area = PI * r * r;
printf("面积 : %.2f", area);
return 0;
}
两者的求别
#define是预处理指令,在编译前运行;const是关键字,在编译过程中执行,
#define定义常量不用指定类型,不进行类型检查,只是简单地文本替换;const定义常量需指定数据类型,会进行类型检查,类型安全性更强。
进制
进制的种类
-
二进制:0、1,满2进1
-
十进制:0 - 9,满10进1
-
十六进制:0 - 9及A-F,满16进1;A-F可大写,可小写
二进制 十进制 十六进制 0 0 0 1 1 1 10 2 2 11 3 3 100 4 4 101 5 5 110 6 6 111 7 7 1000 8 8 1001 9 9 1010 10 A 1011 11 B 1100 12 C 1101 13 D 1110 14 E 1111 15 F 10000 16 10 10001 17 11
C语言中进制表示
- 二进制:以0b或0B开头表示
- 十进制:正常数字表示
- 十六进制:以0x或0X开头表示
#include <stdio.h>
int main()
{
int num1 = 0b10; // 二进制
int num2 = 210; // 十进制
int num3 = 0x1f; // 十六进制
printf("num1=%d \n", num1);
printf("num1=%d \n", num2);
printf("num1=%d \n", num3);
return 0;
}
结果
num1=2
num1=210
num1=31
输出格式
- 使用格式占位符可以将整数以不同进制形式输出
%d:十进制整数
%x:十六进制整数
%#x:前缀为0x的十六进制整数
%#X:前缀为0X的十六进制整数
进制之间的转换
二进制转换十进制
十进制转换二进制
十六进制和十进制转换
将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制。
十进制转换十六进制
将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的十六进制。
机器数和真值
机器数:一个数在计算机的存储形式是二进制数,我们称这些二进制数为机器数,机器数是有符号的,用机器数的最高位存放符号位,0表示正数,1表示负数。 真值:因为机器数带有符号位,所以机器数的形式值不等于其真实表示的值(真值),以机器数10000001为例,其真正表示的值(首位为符号位)为-1,而形式值(首位就是代表1)为129;因此将带符号的机器数的真正表示的值称为机器数的真值。
原码、反码、补码
1.原码 *原码的表示与机器数真值表示的一样,即用第一位表示符号,其余位表示数值。
- 正数的原码:就是它对应的二进制数。
- 负数的原码:它的绝对值对应的二进制数,且最左边位变为1。
- 0的原码:仍然是0 +1 原码:[ 0000 0001 ] -1 原码:[ 1000 0001 ]
2.反码
- 正数的反码:和原码相同
- 负数的反码:在其原码的基础上,符号位不变,其余各位取反
- 0的反码:仍然是0
+1 原码:[ 0000 0001 ] 反码:[ 0000 0001 ]
-1 原码: [ 1000 0001 ] 反码:[ 1111 1110 ]
反码通常是用来由原码求补码或者由补码求原码的过渡码。
3.补码
- 正数的补码:和原码、反码相同
- 负数的补码:反码的基础上加1
- 0的补码:仍然是0 +1 原码:[ 0000 0001 ] 反码:[ 0000 0001 ] 补码:[ 0000 0001 ] -1 原码:[ 1000 0001 ] 反码:[ 1111 1110 ] 补码:[ 1111 1111 ]
总结
- 正数的原码、反码、补码都一样,三码合一
- 负数的反码:它的原码符号位不变,其它位取反(0 -> 1,1 -> 0);负数的补码:它的反码+1
- 0的反码,补码都是0
数据类型
整数类型
整型的类型
- 存储大小的单位
bit(位):计算机中最小的存储单位,表示一个二进制位。
byte(字节):计算机中基本的存储单元,1 byte = 8 bit。
字面量后缀
字面量是源代码中一个固定值的表示法,用于直接表示数据。
- 一个整型字面量默认是int类型。
- 表示long类型字面量,添加后缀l或L。
- 表示long long 类型字面量,添加后缀ll或LL。
- 表示无符号整数字面量,添加后缀 u 或 U, u 和 l 可以结合使用,不分先后,如 ul(无符号long类型)、ULL(无符号 long long类型),lu(无符号 long 类型) 等。
格式占位符
-
%d对应int,%u对应unsigned int。
-
%ld对应long,%lu对应unsigned long。
-
%lld对应long long,%llu对应unsigned long long。
#include <stdio.h> int main() { // short 类型 short a1 = 10; // 等同于 signed short a1 = 10; short a2 = -10; // 等同于 signed short a1 = -10; // unsigned short a3 = -20; unsigned short a3 = 20; printf("a1=%d; a2=%d; a3=%d \n", a1, a2, a3); // a1=10; a2=-10; a3=20 // int 类型 int b1 = 100; // 等同于 signed int a1 = 100; int b2 = -100; // 等同于 signed int a1 = -100; unsigned int b3 = 200u; unsigned b4 = 300U; // 等同于 unsigned int b4 = 300U; printf("b1=%d; b2=%d; b3=%d; b4=%d \n", b1, b2, b3, b4); // b1=100; b2=-100; b3=200; b4=300 // long 类型 long c1 = 1000l; // 等同于 signed long c1 = 1000l; long c2 = -1000L; // 等同于 signed long c2 = -1000L; unsigned long c3 = 2000ul; printf("c1=%ld; c2=%ld; c3=%ld \n", c1, c2, c3); // c1=100; c2=-1000; c3=2000 // long long 类型 long long d1 = 10000ll; // 等同于 signed long long d1 = 10000ll; long long d2 = -10000LL; // 等同于 signed long long d2 = -10000LL; unsigned long long d3 = 20000ULL; printf("d1=%lld; d2=%lld; d3=%lld \n", d1, d2, d3); // d1=10000; d2=-10000; d3=20000 return 0; } 结果: a1=10; a2=-10; a3=20 b1=100; b2=-100; b3=200; b4=300 c1=100; c2=-1000; c3=2000 d1=10000; d2=-10000; d3=20000
精准宽度类型
C 语言的整数类型 (short、int、long) 在不同计算机上,占用的字节宽度可能是不一样的。程序员有时需要精准的字节宽度,以提高代码的可移植性,尤其是嵌入式开发中,使用精确宽度类型可以确保代码在各种平台上的一致性。
标准库的头文件 <stdint.h> 中定义了一些新的类型别名,如下:
| 类型名称 | 含义 |
|---|---|
| int8_t | 8 位有符号整数 |
| int16_t | 16 位有符号整数 |
| int32_t | 32 位有符号整数 |
| int64_t | 64 位有符号整数 |
| uint8_t | 8 位无符号整数 |
| uint16_t | 16 位无符号整数 |
| uint32_t | 32 位无符号整数 |
| uint64_t | 64 位无符号整数 |
#include <stdio.h>
#include <stdint.h>
int main()
{
// 变量 x32 声明为 int32_t 类型,可以保证是32位(4个字节)的宽度。
int32_t x32 = 45933945;
printf("x32=%d\n", x32);
return 0;
}
x32=45933945
浮点类型
| 类型 | 存储大小 | 值范围 | 有效小数位数 |
|---|---|---|---|
| float 单精度 | 4字节 | 1.2E-38到3.4E+38 | 6-9 |
| double | 双精度 | 2.3E-38到1.7E+308 | 15-18 |
| long double长双精度 | 32位:10字节 64位:16字节 | 32位:与double相同或更大 64位:3.4E-4932到1.2E+4932 | 18或更大 |
浮点数注意事项
两种表示方式
- 十进制表示:5.12、512.0f、.512(0.512可以省略0)
- 科学计数法表示:5.12e2、5.12E-2
字面量后缀
- 浮点数字面量默认是double型。
- 表示float类型字面量,须加后缀 f 或 F。
- 如果需要表示long double类型字面量,需加后缀 l 或 L。
格式占位符
- %f 是浮点类型的格式占位符,float类型转换为double类型来处理;默认保存6位小数,%.2f表示保留2位小数。
- %lf在printf中和%f意思相同,也对应double类型,默认保存6位小数,也可以指定保留几位小数,但是在scanf中输入float类型数据时使用 %f,输入double类型数据使用 %lf。
- %Lf对应long double 类型,默认保存6位小数,也可以指定,输入输出long double类型都必须使用%LF占位符。
- %e对应科学计数法的浮点数,可以指定小数位数。
字符类型
字符类型char可以表示一个数字,一个字母,一个符号。
-
char类型的字面量用单引号括起来的单个字符。
-
可以使用转义符\表示特殊含义的字符。
转义字符 说明 \b 退格 \n 换行符 \r 回车符 \t 制表符 " 双引号 ' 单引号 \ 反斜杠 -
多个字称为字符串
格式占位符
使用%c表示char类型。
字符类型的本质
-
char类型本质上是一个整数,是ASCII玛中对应的数字,存储长度是1个字节,char类型也可以进行数字运算。
-
字符型同样分为signed char(有符号类型),unsigned char(无符号类型,signed char 取值-128-到127,无符号类型0-255。
#include <stdio.h>
int main()
{
// char 类型字面量需要使用单引号包裹
char a1 = 'A';
char a2 = '9';
char a3 = '\t';
printf("c1=%c, c3=%c, c2=%c \n", a1, a3, a2);
// char 类型本质上整数可以进行运算
char b1 = 'b';
char b2 = 101;
printf("%c->%d \n", b1, b1);
printf("%c->%d \n", b2, b2);
printf("%c+%c=%d \n", b1, b2, b1 + b2);
// char 类型取值范围
unsigned char c1 = 200; // 无符号char取值范围 0 ~255
signed char c2 = 200; // 有符号char取值范围 -128~127,c2会超出范围
char c3 = 200; // 当前系统,char 默认是 signed char
printf("c1=%d, c2=%d, c3=%d", c1, c2, c3);
return 0;
}
结果:
c1=A, c3= , c2=9
b -> 98
e -> 101
b + e = 199
c1=200, c2=-56, c3=-56
布尔类型
布尔值用于表示真假两种状态,常用于逻辑运算和条件判断。
布尔类型的三种方式
- 借助C语言的宏定义
#include <stdio.h>
// 宏定义
#define BOOL int
#define TURE 1
#define FALSE 0
int main()
{
// 使用整型表示真假两种状态
// int isPass = 0;
// int isOk = 1;
// 借助于宏定义
BOOL isPass = FALSE;
BOOL isOk = TURE;
printf("isPass=%d, isOk=%d \n", isPass, isOk);
if (isPass)
{
printf("Pass");
}
if (isOk)
{
printf("Ok");
}
return 0;
}
输出结果
isPass=0, isOk=1
Ok
- C99标准提供了Bool 型, Bool仍是整数类型,但与一般整型不同的是,_Bool变量只能赋值为0或1,非0的值都会被存储为1。
#include <stdio.h>
int main()
{
// 使用 _BOOL 类型
_Bool isPass = 0;
//_Bool isOk = 1;
_Bool isOk = -4;
printf("isPass=%d, isOk=%d \n", isPass, isOk);
if (isPass)
{
printf("Pass");
}
if (isOk)
{
printf("Ok");
}
return 0;
}
结果
isPass=0, isOk=1
Ok
- (1)C99标准还提供了一个头文件 <stdbool.h> 定义了bool代表_Bool,true代表1,false代表0。
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool isPass = false;
bool isOk = true;
printf("isPass=%d, isOk=%d \n", isPass, isOk);
if (isPass)
{
printf("Pass");
}
if (isOk)
{
printf("Ok");
}
return 0;
}
结果
isPass=0, isOk=1
Ok
获取数据的存储大小
sizeof可以获取数据类型或变量、字面量的存储大小,单位是字节,sizeof返回一个size_t类型的无符号整数值,格式占位符是%zu。
数据类型的转换
转换规则
- 不同类型整数进行运算,窄类型整数自动转换为宽类型整数。
- 不同类型浮点数进行运算,精度小的类型自动转换为精度大的类型。
- 整数与浮点数进行运算,整数自动转换为浮点数。
强制类型转换
(类型名)变量、常量或表达式
#include <stdio.h>
int main()
{
double d1 = 1.934;
double d2 = 4.2;
int num1 = (int)d1 + (int)d2; // d1转为1,d2转为4,结果是5
int num2 = (int)(d1 + d2); // d1+d2=6.134,6.134转为6
int num3 = (int)(3.5 * 10 + 6 * 1.5); // 35.0 + 9.0 = 44.0 -> int = 44
printf("num1=%d \n", num1);
printf("num2=%d \n", num2);
printf("num3=%d \n", num3);
return 0;
}
结果
num1=5
num2=6
num3=44
算术运算符
自增自减
- 自增、自减运算符可以写在操作数的前面也可以写在操作数后面,不论前面还是后面,对操作数的副作用是一致的。
- 自增、自减运算符在前在后,对于表达式的值是不同的。 如果运算符在前,表达式的值是操作数自增、自减之后的值;如果运算符在后,表达式的值是操作数自增、自减之前的值。
#include <stdio.h>
int main()
{
int i1 = 10, i2 = 20;
int i = i1++;
printf("%d\n", i); // 10
printf("%d\n", i1); // 11
i = ++i1;
printf("%d\n", i); // 12
printf("%d\n", i1); // 12
i = i2--;
printf("%d\n", i); // 20
printf("%d\n", i2); // 19
i = --i2;
printf("%d\n", i); // 18
printf("%d\n", i2); // 18
return 0;
}
输出结果:
10
11
12
12
20
19
18
18
逻辑运算符
| 运算符 | 描述 | 操作数个数 | 表达式的值 | 副作用 | ||
|---|---|---|---|---|---|---|
| && | 逻辑与 | 2 | 0 或 1 | 无 | ||
| 逻辑或 | 2 | 0 或 1 | 无 | |||
| ! | 逻辑非 | 1 | 0 或 1 | 无 |
逻辑与&&
- 如果两个操作数都为真(非零),那么表达式的值为真,否则为假。
- 如果第一个操作数为真,第二个操作数没有计算的必要了,这种现象称为短路现象。
#include <stdio.h>
int main()
{
double score = 70;
if (score >= 70 || score <= 80)
{
printf("ok1 \n");
}
else
{
printf("ok2 \n");
}
int a = 10, b = 99;
// 短路现象
if (a > 5 || b++ > 100)
{ //
printf("ok100 \n");
}
printf("b=%d\n", b);
return 0;
}
输出结果:
ok1
ok100
b=99
逻辑或||
- 只要有一个操作数为真,表达式的值就为真;两个操作数都为假,表达式的值为假。
- 如果第一个操作数为真,第二个操作数没有计算的必要了,这种现象称为短路现象。
逻辑非!
- 操作数状态取反作为表达式的值。
#include <stdio.h>
int main()
{
int score = 100;
int res = score > 99;
if (res)
{
printf("hello, tom \n");
}
if (!res)
{
printf("hello,jack \n");
}
return 0;
}
输出结果:
hello, tom
赋值运算符
| 运算符 | 描述 | 操作数个数 | 表达式的值 | 副作用 | |
|---|---|---|---|---|---|
| = | 赋值 | 2 | 左边操作数的值 | 有 | |
| + | 相加赋值 | 2 | 左边操作数的值 | 有 | |
| -= | 相减赋值 | 2 | 左边操作数的值 | 有 | |
| *= | 相乘赋值 | 2 | 左边操作数的值 | 有 | |
| /= | 相除赋值 | 2 | 左边操作数的值 | 有 | |
| *%= | 取余赋值 | 2 | 左边操作数的值 | 有 | |
| <<= | 左移赋值 | 2 | 左边操作数的值 | 有 | |
| >>= | 右移赋值 | 2 | 左边操作数的值 | 有 | |
| &= | 按位与赋值 | 2 | 左边操作数的值 | 有 | |
| ^= | 按位异或赋值 | 2 | 左边操作数的值 | 有 | |
| = | 按位或赋值 | 2 | 左边操作数的值 | 有 |
- 赋值运算符的第一个操作数(左值)必须是变量的形式,第二个操作数可以是任何形式的表达式。
- 赋值运算符的副作用针对第一个操作数。
- 左移赋值,右移赋值,按位与赋值,按位异或赋值,按位或赋值;均需要换算成二进制计算。
- 异或相同为0,不同为1
#include<stdio.h>
int main()
{
int a=1;
int b=2;
int c1=2;
int c2=2;
int c3=2;
int c4=2;
int c5=2;
c1<<=b;//左移赋值
printf("%d\n",c1);
c2>>=b;//右移赋值
printf("%d\n",c2);
c3&=a;//按位与赋值
printf("%d\n",c3);
c4^=b;//按位异或赋值
printf("%d\n",c4);
c5|=4;//按位或赋值
printf("%d\n",c5);
}
结果
8
0
0
0
6
位运算符
| 运算符 | 描述 | 操作数个数 | 副作用 | |
|---|---|---|---|---|
| & | 按位与 | 2 | 无 | |
| 按位或 | 2 | 无 | ||
| 按位异或 | 2 | 无 | ||
| ~ | 按位取反 | 2 | 无 | |
| << | 按位左移 | 2 | 无 | |
| >> | 按位右移 | 2 | 无 |
按位与、按位或、按位异或
#include <stdio.h>
int main()
{
int a = 17;
int b = -12;
printf("a&b=%d\n", a & b); // a&b=16
printf("a|b=%d\n", a | b); // a|b=-11
printf("a^b=%d\n", a ^ b); // a^b=-27
return 0;
}
输出结果:
a&b=16
a|b=-11
a^b=-27
按位取反
- 如果正数取反,正数+1,前边加个负号,负数取反,|负数|-1
#include <stdio.h>
int main()
{
int a = 17;
int b = -12;
// 按位非
printf("~a=%d\n", ~a);
printf("~b=%d\n", ~b);
return 0;
}
输出结果:
~a=-18
~b=11
按位左移、右移
#include <stdio.h>
int main()
{
int a = 17;
int b = -12;
// 按位左移
printf("a<<2=%d\n", a << 2); // a<<2=68
printf("b<<2=%d\n", b << 2); // b<<2=-48
// 按位右移
printf("a>>3=%d\n", a >> 3); // a>>3=2
printf("b>>3=%d\n", b >> 3); // b>>3=-2
return 0;
}
输出结果:
a<<2=68
b<<2=-48
a>>3=2
b>>3=-2
三元运算符
- 条件表达式?表达式1:表达式2
- 如果条件表达式为非0(真),整个表达式的值是表达式1
- 如果条件表达式为0(假),整个表达式的值是表达式2
运算符优先级
- 运算符优先级不用刻意地去记忆,总体上:一元运算符 > 算术运算符 > 关系运算符 > 逻辑运算符 > 三元运算符 > 赋值运算符。
分支控制语句
多向分支 else if
if (条件表达式1)
{
执行代码块1;
}
else if (条件表达式2)
{
执行代码块2;
}
...
else
{
执行代码块n;
}
多项分支 switch
switch (表达式)
{
case 常量值1:
语句块1;
break;
case 常量值2:
语句块2;
break;
… case 常量值n:
语句块n;
break;
default:
语句块n + 1;
}
- switch后面表达式的值必须是一个整型(char、short, int, long等)或枚举类型。
- case后面的值必须是常量,而不能是变量
- default是可选的,当没有匹配的case时,执行default
- reak语句可以使程序跳出switch语句块,如果没有break,会执行下一个case 语句块,直到遇到break或者执行到switch结尾,这个现象称为穿透
switch 和 else if的比较
- 如果判断条件是判等,而且符合整型、枚举类型,虽然两个语句都可以使用,建议使用swtich语句。
- 如果判断条件是区间判断,大小判断等,使用else if。
循环控制语句
while循环
while (循环条件表达式)
{
循环体语句;
}
- 当循环条件表达式成立,就执行循环体语句,直到条件不成立停止循环
- 为避免死循环,循环条件表达式不能永远成立,且随着循环次数增加,应该越来越趋向于不成立
不确定循环直到循环表达式不成立之前,不确定循环次数,不需要循环变量。
实现需求:输入6位数密码,直到密码匹配成功结束循环。
#include <stdio.h>
int main()
{
// 记录正确密码
int pwd1 = 123456;
// 定义变量用于获取输入的密码
int pwd2;
// 循环
while (pwd1 != pwd2)
{
printf("请输入6位数密码:");
scanf("%d", &pwd2);
}
printf("密码正确,欢迎回家!");
return 0;
}
do...while循环
do
{
循环体语句;
} while (循环条件表达式);
- do…while循环是先执行再判断,但只有第一次循环语句的执行没有经过判断,以后的每一次仍然先经过判断
- while后面的分号不能省略
输入6位数密码,直到密码匹配成功结束循环。
#include <stdio.h>
int main()
{
// 正确密码
int pwd1 = 123456;
// 定义变量用于获取输入的密码
int pwd2;
// 循环
do
{
printf("请输入6位数密码:");
scanf("%d", &pwd2);
} while (pwd1 != pwd2);
printf("密码正确,欢迎回家!");
return 0;
}
while和do while 的差异
#include <stdio.h>
int main()
{
// while 循环 一次也不会执行
int n = 10;
while (n > 10)
{
printf("%d \n", n);
n++;
}
// do while 陷入死循环
n = 10;
do
{
printf("%d \n", n);
n++;
} while (n > 10);
return 0;
}
#### for循环
for (循环变量初始化; 循环条件表达式; 循环变量变化)
{
循环条语句;
}
- 循环变量初化只执行一次,且循环开始前就执行
- 循环条件表达式每次循环都执行,同while循环一样,每次先判断后执行循环体语句
- 循环标记变量变化每次循环都执行,在大括号中循环体语句之后执行
#include <stdio.h>
int main()
{
// 正确密码
int pwd1 = 123456;
// 定义变量用于获取输入的密码
int pwd2;
// 循环
for (; pwd1 != pwd2;)
{
printf("请输入6位数密码:");
scanf("%d", &pwd2);
}
printf("密码正确,欢迎回家!");
return 0;
}
5)案例 – 特殊结构的for循环
#include <stdio.h>
int main()
{
// 标准结构
for (int i = 1; i < 10; i += 2)
{
printf("%d ", i);
}
printf("\n\n");
// 循环变量写在外面
int i = 1;
for (; i < 10; i += 2)
{
printf("%d ", i);
;
}
printf("\n\n");
// 循环变量写在外面 循环标记变量变化写在大括号中
i = 1;
for (; i < 10;)
{
printf("%d ", i);
i += 2;
}
printf("\n\n");
// 使用两个循环标记变量
for (int x = 1, y = 1; x <= 15, y <= 10; x++, y++)
{
printf("%d %d \n", x, y);
}
printf("\n\n");
// for 后面括号中什么都不写 死循环
for (;;)
{
printf("死循环 \n");
}
return 0;
}
多重循环
分别打印出以下两种形式的九九乘法表。
(1)第一种形式
#include <stdio.h>
int main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%d\t", j, i, i * j);
}
printf("\n");
}
return 0;
}
(2)第二种形式
#include <stdio.h>
int main()
{
for (int i = 9; i >= 1; i--)
{
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%d\t", j, i, i * j);
}
printf("\n");
}
return 0;
}
(3)第三种形式
#include <stdio.h>
int main()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9 - i; j++)
{
printf("\t");
}
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%d\t", j, i, i * j);
}
printf("\n");
}
return 0;
}
(4)第四种形式
#include <stdio.h>
int main()
{
for (int i = 9; i >= 1; i--)
{
for (int j = 1; j <= 9 - i; j++)
{
printf("\t");
}
for (int j = 1; j <= i; j++)
{
printf("%d*%d=%d\t", j, i, i * j);
}
printf("\n");
}
return 0;
}
跳转控制语句
break
- break语句用于终止某个语句块的执行,用在switch语句或者循环语句中。
编写程序,要求输入一个数字,判断该数字是否是质数。
说明:质数指只能被1和自身整除且大于1的数字。
#include <stdio.h>
#include <stdbool.h>
int main()
{
// 获取输入的数字
int num;
printf("输入一个数字:");
scanf("%2d", &num);
// 定义变量,标记是否为质数
// 大于1的数字先标记为真,再通过循环看是否推翻; 小于1的数字直接标记为假
_Bool isPrime = num > 1 ? 1 : 0;
// 循环判断
for (int i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
isPrime = 0;
break;
}
}
// 输出结果
if (isPrime)
{
printf("%d 是质数!", num);
}
else
{
printf("%d 不是质数!", num);
}
return 0;
}
continue
- continue语句用于结束本次循环,继续执行下一次循环。
输出100以内(包括100)的数字,跳过那些7的倍数或包含7的数字。
#include <stdio.h>
int main()
{
for (int i = 1; i <= 100; i++)
{
// i % 7 判断 7 的倍数
// i % 10 判断个位上带7的数字
// i / 10 判断十位上带7的数字
if (i % 7 == 0 || i % 10 == 7 || i / 10 == 7)
{
continue; // 跳过
}
printf("%d\n", i);
}
return 0;
}
goto语句
- goto语句是一种跳转语句,它允许程序控制流程在代码中跳转到带有标签(label)的语句处,标签(label)的名称可以自行设置,需要满足标识符规范。
- 注意,我们在开发中不建议使用goto语句,但我们需要掌握 goto 语句的执行流程,以能够看懂其他开发者的代码中可能出现的 goto 语句。
goto 标签名 // 跳转到指定的标签(label)处
...
标签名: // 定义一个标签(label)
语句;
goto 后面如果引用了没有定义的标签,编译器会报错!
使用 goto 语句实现语句跳转。
#include <stdio.h>
int main()
{
printf("start \n");
goto lable1; // lable1是标签名
printf("ok1 \n");
printf("ok2 \n");
lable1:
printf("ok3 \n");
printf("ok4 \n");
return 0;
}
输出结果:
start
ok3
ok4