例如,可以使用char声明一个字符变量如下:
char ch = 'A';//此处,ch 是一个 char 类型的变量,其值为字符 'A'。
char 还可以用于声明字符数组(字符串):
char str[10] = "Hello";
这里,str 是一个字符数组,用于存储字符串 "Hello",数组大小为 10,包括一个额外的空字符 \0,用于表示字符串的结束。
此外,char 也可以用于声明函数的返回类型或参数类型,表示函数返回或接受的是字符值。
char getGrade(float score) {
// 根据分数返回对应的等级
// ...
}
在上述示例中,getGrade 是一个函数,接受一个 float 类型的参数 score,并返回一个 char 类型的等级。
总结起来,char 关键字用于声明字符型变量、字符数组以及函数的返回类型和参数类型。
注:char 占一个字节,也就是 8 个二进制位,但它表示的是有符号的类型,所以表示的范围是 -128~127 ;uchar 表示无符号的类型,所以表示的范围是 0~255
例如,可以使用 double 声明一个双精度浮点数变量如下:
double num = 3.14159;
在这个例子中,num 是一个 double 类型的变量,其值为近似 π 的双精度浮点数。
double 可以提供更高的精度和表示范围,相对于 float 类型来说。通常用于需要更高精度的计算或需要处理更大范围的数据时使用。类似地,double 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是双精度浮点数。
double calculateAverage(double arr[], int size) {
// 计算数组的平均值并返回
// ...
}
在上述示例中,calculateAverage 是一个函数,接受一个 double 类型的数组 arr[] 和一个整数 size,并返回一个 double 类型的平均值。综上所述,double 关键字用于声明双精度浮点数变量、函数的返回类型和参数类型。
注:double 占的字节:16 位编译器下,double 占 8 个字节;32 位编译器下,double 占 8 个字节;64 位编译器下,double 占 8 个字节。
枚举类型允许我们为一组相关的常量赋予有意义的名称。下面是一个使用 enum 声明枚举类型的示例:
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
在上述示例中,enum Day 声明了一个名为 Day 的枚举类型。它定义了一周中的每一天,并为它们赋予了有意义的名称。默认情况下,第一个常量的值为 0,每个后续常量的值递增1。
可以使用这个枚举类型来声明变量,并将其设置为枚举中定义的常量:
enum Day today = WEDNESDAY;
在这个例子中,today 是一个 enum Day 类型的变量,它被赋予了枚举中的常量值 WEDNESDAY。
枚举类型作为整数的常量集合,可以用于提高代码的可读性和可维护性。它使得我们可以使用有意义的符号来表示特定的值,而不是使用具体的数字。
需要注意,枚举类型在内存中占据整数类型的大小,通常是4个字节。如果需要更小的枚举类型,可以使用 enum 的特定语法进行显式指定,例如 enum Day : unsigned char。
注:enum 是计算机编程语言中的一种数据类型。枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等。如果把这些量说明为整型,字符型或其它类型显然是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。
例如,可以使用 float 声明一个单精度浮点数变量如下:
float num = 3.14;
在这个例子中,num 是一个 float 类型的变量,其值为近似 π 的单精度浮点数。
float 是一种用于表示小数的数据类型,通常使用于需要高精度计算的情况。它比整数类型的范围更大,并且可以存储小数部分。
同样地,float 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是单精度浮点数。
float calculateAverage(float arr[], int size) {
// 计算数组的平均值并返回
// ...
}
在上述示例中,calculateAverage 是一个函数,接受一个 float 类型的数组 arr[] 和一个整数 size,并返回一个 float 类型的平均值。
注: float 是C语言的基本数据类型中的一种,表示单精度浮点数,占 4 个字节。
例如,可以使用 int 声明一个整型变量如下:
int num = 42;
在这个例子中,num 是一个 int 类型的变量,其值为 42。
int 是一种用于表示整数的数据类型,它可以存储整数值(正数、负数或零)。通常使用 int 来处理整数运算和存储整数数据。
同样地,int 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是整数值。
int calculateSum(int a, int b) {
// 计算两个整数的和并返回
// ...
}
在上述示例中,calculateSum 是一个函数,接受两个 int 类型的参数 a 和 b,并返回一个 int 类型的和。
注:数据类型占内存的位数与操作系统的位数以及编译器有关,一般情况下在当前主流的编译器中int 类型无论在 32 位或 64 位系统中都是 4 个字节。
例如,可以使用 long 声明一个长整型变量如下:
long num = 1234567890;
在这个例子中,num 是一个 long 类型的变量,其值为 1234567890。
long 是一种用于表示较大范围整数的数据类型,在不同编译器中的长度可能有所不同。通常情况下,它的长度为 4 个字节(32 位)或 8 个字节(64 位),比 int 类型的范围更大,可以存储更大的整数值。
同样地,long 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是长整型值。
long calculateFactorial(long n) {
// 计算 n 的阶乘并返回结果
// ...
}
在上述示例中,calculateFactorial 是一个函数,接受一个 long 类型的参数 n,并返回一个 long 类型的阶乘结果
注:C语言中 long 是4个字节,是一种数据类型,有两种表现形式:有符号和无符号。
在有符号中,long 的表示数的范围为:-2147483648~2147483647
在无符号中,long 的表示数的范围为:0~4294967295
例如,可以使用 short 声明一个短整型变量如下:
short num = 100;
在这个例子中,num 是一个 short 类型的变量,其值为 100。
short 是一种用于表示较小范围整数的数据类型,在不同编译器中的长度可能有所不同。通常情况下,它的长度为 2 个字节(16 位),比 int 类型的范围更小,可以存储更小的整数值。
同样地,short 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是短整型值。
short calculateSquare(short n) {
// 计算 n 的平方并返回结果
// ...
}
在上述示例中,calculateSquare 是一个函数,接受一个 short 类型的参数 n,并返回一个 short 类型的平方结果。
注:short 是占两个字节。short 在C语言中是定义一种整型变量家族的一种,short i ;表示定义一个短整型的变量 i 。
依据程序编译器的不同short定义的字节数不同。标准定义short短整型变量不得低于16位,即两个字节。编译器头文件夹里面的limits.h定义了short能表示的大小:SHRT_MIN~SHRT_MAX。在32位平台下如windows(32位)中short一般为16位。
在 C 语言中,整数类型默认为有符号类型。因此,当使用 int、short 或 long 这些整数类型时,默认情况下它们都是有符号的。
例如,可以使用 signed 声明一个有符号整型变量如下:
signed int num = -42;
在这个例子中,num 是一个有符号的整型变量,其值为 -42。
类似地,可以使用 signed 声明有符号的短整型或长整型变量:
signed short num1 = -100;signed long num2 = -1234567890;
signed 关键字的作用是明确地指定变量的有符号性质,尽管在大多数情况下它并不是必需的。
同样地,signed 也可以用来声明函数的返回类型或参数类型,表示函数返回或接受的是有符号类型的值。
signed int calculateSum(signed int a, signed int b) {
// 计算两个有符号整数的和并返回结果
// ...
}
在上述示例中,calculateSum 是一个函数,接受两个有符号的整数参数 a 和 b,并返回一个有符号整型的和。
注:signed 是默认的,表示这个变量是有符号的,可以存储整数和负数。
signed 存储符号是有代价的,代价就是存储空间中的一个比特位专门用来存储符号,这一位不能表示数值。一般来说,同类型的 signed 能够存储的数的绝对值大小要小于 undigned 。
结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起形成一个逻辑上的实体。使用结构体可以更方便地表示和操作一组相关的数据。要声明一个结构体变量,需要先定义结构体的结构并指定其成员。例如,我们可以定义一个表示学生的结构体:
struct Student {
int id;
char name[50];
int age;
};
在这个例子中,我们定义了一个名为 Student 的结构体,它包含三个成员:id(整型)、name(字符数组)和 age(整型)。
然后,我们可以声明一个结构体变量并初始化它:
struct Student student1 = {1, "Alice", 20};
在这个例子中,我们声明了一个名为 student1 的结构体变量,并通过花括号初始化了它的成员。
除了声明结构体变量,struct 关键字也可以用于声明结构体类型的函数的返回类型或参数类型。
struct Student findStudentById(int id) {
// 根据学生 ID 查找并返回相应的学生结构体
}
在上述示例中,findStudentById 是一个函数,接受一个整型参数 id,并返回一个 Student 结构体类型的值。
注:在C语言中,可以使用结构体( Struct )来存放一组不同类型的数据。
结构体的定义形式为: struct 结构体名{结构体所包含的变量或数组};
结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员( Member )。
共用体是一种特殊的数据类型,它允许在同一块内存空间中存储不同类型的数据。共用体的所有成员共享同一块内存,即同一时间只能保存其中一个成员的值。
要声明一个共用体,需要定义共用体的结构并指定其成员。例如,我们可以定义一个表示联合身份证信息的共用体:
union IDInfo {
int id;
char name[50];
};
在这个例子中,我们定义了一个名为 IDInfo 的共用体,它包含两个成员:id(整型)和 name(字符数组)。
然后,我们可以声明一个共用体变量,并对其中一个成员进行赋值:
union IDInfo info;
info.id = 123456;
在这个例子中,我们声明了一个名为 info 的共用体变量,并对其 id 成员赋值。
共用体的特点是它的所有成员共享同一块内存空间,因此不同成员可能会有相互覆盖的情况。我们只能同时访问一个共用体成员的值。
共用体也可以作为函数的返回类型或参数类型。
union IDInfo getIdInfo() {
// 根据某种逻辑获取身份证信息并返回一个 IDInfo 共用体
}
在上述示例中,getIdInfo 是一个函数,它根据某种逻辑获取身份证信息,并返回一个 IDInfo 共用体。
注:C语言中的 union 是联合体,就是一个多个变量的结构同时使用一块内存区域,区域的取值大小为该结构中长度最大的变量的值。
使用 unsigned 的好处是可以扩展类型的取值范围,允许表示更大的正数。然而,由于无符号类型不包括负数,因此在进行运算时需要注意溢出和边界情况的处理。
注:整型的每一种都有无符号( unsigned )和有符号( signed )两种类型( float 和 double 总是带符号的)
在默认情况下声明的整型变量都是有符号的类型( char 有点特别),如果需声明无符号类型的话就需要在类型前加上 unsigned 。
无符号版本和有符号版本的区别就是无符号类型能保存 2 倍于有符号类型的数据,比如 16 位系统中一个 int 能存储的数据的范围为 -32768~32767 ,而 unsigned 能存储的数据范围则是 0~65535。
声明函数无返回值或无参数: 在函数声明或定义时,可以使用 void 关键字表示该函数没有返回值或没有参数。例如:
void printHello() {
printf("Hello!\n");
}
void doSomething(int x, int y) {
// 函数体
}
在上述示例中,printHello 函数没有返回值也没有参数,而 doSomething 函数有两个参数。使用 void 可以清楚地表明函数的特性。声明无类型指针: 在 C 语言中,void 指针可以用于声明指向任意类型的指针。例如:
void* genericPointer;int* intPointer;float* floatPointer;
int main() {
int num = 10;
genericPointer = # // void 指针可以指向任意类型的指针
intPointer = (int*)genericPointer; // 需要进行显式类型转换
printf("Value: %d\n", *intPointer); // 输出结果:Value: 10
return 0;
}
在上述示例中,我们声明了一个无类型指针 genericPointer,它可以指向任意类型的数据。在使用该指针时,需要进行显式的类型转换。
需要注意的是,在使用无类型指针时,需要小心处理类型转换和指针的解引用,以确保不会导致类型错误和未定义行为。
注:void 被翻译为"无类型",相应的 void * 为"无类型指针"。常用在程序编写中对定义函数的参数类型、返回值、函数中指针类型进行声明。
for 循环由三个部分组成:初始化表达式、循环条件和循环迭代器。语法如下:
for (初始化表达式; 循环条件; 循环迭代器) {
// 循环体
}
每个部分的含义如下:
A.初始化表达式:在循环开始前执行一次,用于初始化循环变量。
B.循环条件:在每次循环开始前被求值,如果条件表达式为真,则继续执行循环体;如果条件表达式为假,则跳出循环。
C.循环迭代器:在每次循环结束后执行一次,用于更新循环变量的值。
下面是一个示例,演示了 for 循环的使用:
#include
int main() {
// 使用 for 循环打印数字 1 到 5
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
printf("\n");
return 0;
}
输出结果为:
1 2 3 4 5
在上述示例中,通过 for 循环,我们初始化了循环变量 i 的值为 1,设置循环条件为 i 小于等于 5,在每次循环结束后使得 i 自增 1。通过循环的迭代,我们成功打印了数字 1 到 5。
for 循环在实际应用中非常灵活,可以根据需要进行各种计数、条件判断以及递增递减操作,以满足具体的循环需求。
注:for 是C语言中的一个关键字,主要用来控制循环语句的执行
do-while 循环的语法如下:
do {
// 循环体
} while (条件);
do-while 循环先执行循环体,然后再判断条件,只有当条件为真时,才会继续执行下一次循环。即使条件一开始就为假,循环体至少会被执行一次。下面是一个示例,演示了 do-while 循环的使用:
#include
int main() {
int num = 1;
do {
printf("%d ", num);
num++;
} while (num <= 5);
printf("\n");
return 0;
}
输出结果为:
1 2 3 4 5
在上述示例中,我们使用 do-while 循环打印数字 1 到 5。首先,我们初始化了变量 num 的值为 1,然后在 do 后面的花括号内打印 num 的值,并将 num 自增 1。然后在 while 条件中判断 num 是否小于等于 5,如果是,则继续执行下一次循环,否则跳出循环。
需要注意的是,由于 do-while 循环先执行循环体再判断条件,所以循环体至少会被执行一次,即使条件一开始就不满足。这点与 while 和 for 循环有所不同。
do-while 循环常用于需要至少执行一次循环体的场景,或者在循环体执行之前不确定循环条件的情况下。
注:C语言中 do 是执行某代码块的意思,do 关键字不能单独使用,通常用在 do...while
循环中。
在C语言中,do...while 循环是在循环的尾部检查它的条件,do...while 循环与 while 循环类似,但是 do...while 循环不管是真是假都要确保至少执行一次循环。
while 循环的语法如下:
while (条件) {
// 循环体
}
在执行 while 循环时,首先会判断条件是否为真。如果条件为真,则执行循环体中的代码块;如果条件为假,则跳过循环体,继续执行后续的代码。
下面是一个示例,演示了 while 循环的使用:
#include
int main() {
int num = 1;
while (num <= 5) {
printf("%d ", num);
num++;
}
printf("\n");
return 0;
}
输出结果为:
1 2 3 4 5
在上述示例中,我们使用 while 循环打印数字 1 到 5。首先,我们初始化了变量 num 的值为 1,然后在 while 后的括号内写下条件 num <= 5。接着,循环体中的代码会被执行,即打印当前的 num 值,并将 num 加 1。然后,再次判断条件 num <= 5 是否为真,如果为真,则继续执行下一次循环,否则跳出循环。
需要注意的是,在 C 语言中,条件表达式的值为 0 表示假,非零值表示真。因此,循环条件的判断是通过条件表达式的结果来确定的。
while 循环常用于根据条件来重复执行代码的场景,例如对数组、字符串进行遍历或根据用户输入进行循环等。在编写 while 循环时,需要确保在循环体中更新循环条件,以防止循环成为无限循环。
注:while 语句创建了一个循环,重复执行直到测试表达式为假或0。
while 语句是一种入口条件循环,也就是说,在执行多次循环之前已决定是否执行循环。因此,循环有可能不被执行。
循环体可以是简单语句,也可以是复合语句。
在循环体内部使用 break 可以立即退出当前的循环,不再执行循环体内剩余的代码,并且程序会继续执行循环之后的代码。
下面是一个示例,演示了 break 的使用:
#include
int main() {
int num = 1;
while (num <= 10) {
printf("%d ", num);
if (num == 5) {
break;
}
num++;
}
printf("\n");
return 0;
}
输出结果为:
1 2 3 4 5
在上述示例中,我们使用 while 循环打印数字 1 到 10。在循环体内部,我们加入了一个条件判断 if (num == 5),当 num 的值等于 5 时,执行 break 语句跳出循环。因此,在执行到 num 等于 5 的时候,循环被提前终止,不再继续执行循环体内的代码。
需要注意的是,break 只能跳出最内层的循环,如果有多重嵌套的循环,则 break 只会跳出当前的循环,而不会影响外层的循环。
break 语句常用于在满足某个条件时提前退出循环,以避免不必要的循环执行。
注:C 语言中 break 语句有以下两种用法:
终止,且程序流将继续执行紧接着循环的下一条语句。当 break 语句出现在一个循环内时,循环会立即
它可用于终止 switch 语句中的一个 case 。
如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。
使用 continue 关键字时,程序会跳过当前循环体内剩余的代码,并直接进入下一次循环的迭代,不再执行当前循环体内 continue 之后的代码。
下面是一个示例,演示了 continue 的使用:
#include
int main() {
int num = 1;
while (num <= 5) {
if (num == 3) {
num++;
continue;
}
printf("%d ", num);
num++;
}
printf("\n");
return 0;
}
输出结果为:
1 2 4 5
在上述示例中,我们使用 while 循环打印数字 1 到 5。在循环体内部,我们加入了一个条件判断 if (num == 3),当 num 的值等于 3 时,执行 continue 语句。因此,在执行到 num 等于 3 的时候,当前循环被提前结束,跳过 printf 语句,直接进行下一轮循环迭代。
需要注意的是,continue 只会结束当前循环的迭代,然后开始下一轮循环,它不会跳出整个循环。因此,循环仍然会继续执行,只是跳过了 continue 之后的代码。
continue 语句常用于在满足某个条件时结束当前迭代,但仍然希望循环继续执行下一次迭代。
注:continue 跳过本次循环,进入下一次。而 break 是直接跳出循环。
比如 for 循环,遇到 contimue 生效后,直接重新执行 for 的表达式,也就是本循环中 continue 下面的语句就不执行,跳过循环中的一次。
contimue 其作用为结束本次循环。即跳出循环体中下面尚未执行的语句,对于 while 循环,继续求解循环条件。而对于 for 循环程序流程接着求解 for 语句头中的第三个部分 expression 表达式。
continue 语句只结束本次循环,而不终止整个循环的执行。而 break 语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
基本的 if 语法结构如下:
if (condition) {
// 如果条件为真,执行这里的代码
}
condition 是一个布尔表达式,它的结果必须是真(非零)或假(零)。如果 condition 的值为真,那么紧随其后的代码块就会被执行;如果 condition 的值为假,那么这个代码块会被跳过。
此外,if 语句还可以与 else 一起使用,以提供对条件不满足时的备选执行路径。完整的 if-else 语法如下:
if (condition) {
// 如果条件为真,执行这里的代码
} else {
// 如果条件为假,执行这里的代码
}
当 condition 的值为真时,代码块内的代码会被执行;当 condition 的值为假时,将会执行 else 后面的代码块。
下面是一个示例,演示了 if 和 if-else 的使用:
#include
int main() {
int num = 5;
if (num > 0) {
printf("num 是正数\n");
}
if (num % 2 == 0) {
printf("num 是偶数\n");
} else {
printf("num 是奇数\n");
}
return 0;
}
输出结果为:
num 是正数num 是奇数
在上述示例中,我们使用 if 和 if-else 条件语句来根据条件对变量 num 的值进行判断并执行不同的代码块。
需要注意的是,if 语句中的代码块可以是单行或多行,而且大括号 {} 是可选的。如果代码块只有一行,可以不使用大括号,但建议始终使用大括号以增强代码的可读性和减少错误发生的可能性。
另外,if 语句还可以与嵌套的 if、else if 来构建更复杂的条件判断逻辑。
注:if (表达式) {语句;}
用于单分支选择结构;
如含有交叉关系,使用并列的if语句;
基本的 if-else 结构如下:
if (condition) {
// 如果条件为真,执行这里的代码
} else {
// 如果条件为假,执行这里的代码
}
当 if 条件的结果为真时,会执行紧跟在 if 后面的代码块;当 if 条件的结果为假时,会执行紧跟在 else 后面的代码块。
下面是一个示例,演示了 if-else 的使用:
#include
int main() {
int num = 5;
if (num > 0) {
printf("num 是正数\n");
} else {
printf("num 是负数或零\n");
}
return 0;
}
输出结果为:
num 是正数
在上述示例中,我们使用 if-else 条件语句对变量 num 的值进行判断。如果 num > 0 的条件为真,将会执行 if 后面的代码块;如果条件为假,则会执行 else 后面的代码块。
需要注意的是,else 本身不能单独存在,必须与 if 搭配使用。if-else 只会执行其中一个代码块,不会同时执行两个代码块。
此外,if-else 结构还可以进行多层嵌套,构建更复杂的条件判断逻辑。例如:
c
if (condition1) {
// 如果条件1为真,执行这里的代码
} else if (condition2) {
// 如果条件2为真,执行这里的代码
} else {
// 如果条件1和条件2都为假,执行这里的代码
}
在多层嵌套的 if-else 结构中,每个 else if 语句用于添加额外的条件判断分支,而最后的 else 语句则是所有条件都不成立时的备选分支。
注: if (表达式) {语句;} else {语句;}
在C语言中 else 是与 if 一起使用的一个关键字,表示如果满足if条件则不执行 else ,否则执行else 。
goto 语句的基本语法如下:
goto label;
其中,label 是用户定义的标签(可以是任何有效的标识符),它通常位于 goto 语句之前。当程序执行到 goto 语句时,会立即跳转到对应的标签处,并继续执行标签所在的代码块。
下面是一个示例,演示了 goto 语句的使用:
#include
int main() {
int i = 0;
loop:
printf("%d\n", i);
i++;
if (i < 5) {
goto loop;
}
return 0;
}
输出结果为:01234
在上述示例中,我们使用了 goto 语句实现了一个简单的循环。在 main 函数中,首先定义了一个标签 loop,然后使用 goto 语句将程序的执行跳转到该标签处。在 loop 标签所在的代码块中,我们打印变量 i 的值并递增,然后检查 i 是否小于 5,如果条件为真,则再次跳转到 loop 标签处,否则程序继续向下执行。
需要注意的是,过度使用 goto 语句可能导致代码难以理解和维护,因此在实际编程中应谨慎使用。通常情况下,可以通过循环结构(如 for、while)和条件语句(如 if、else)来实现代码逻辑的控制,而不必过度依赖 goto 语句。
注:goto 语句可以使程序在没有任何条件的情况下跳转到指定的位置,所以 goto 语句又被称为是无条件跳转语句。
使用 goto 语句只能 goto 到同一函数内,而不能从一个函数里 goto 到另外一个函数里。
不能从一段复杂的执行状态中的位置 goto 到另外一个位置,比如,从多重嵌套的循环判断中跳出去就是不允许的。
应该避免向两个方向跳转。这样最容易导致"面条代码"。
switch 语句的基本语法如下:
switch (expression) {
case value1:
// 当 expression 等于 value1 时执行的代码
break;
case value2:
// 当 expression 等于 value2 时执行的代码
break;
// 更多 case 分支...
default:
// 当 expression 不等于任何一个 case 值时执行的代码
break;
}
其中,expression 是一个表达式,其值会与每个 case 的常量值进行比较。如果 expression 的值与某个 case 的常量值相等,则执行该 case 下的代码块。如果 expression 的值与所有 case 的常量值都不相等,则执行 default 下的代码块(可选)。
下面是一个示例,演示了 switch 语句的使用:
#include
int main() {
int choice = 2;
switch (choice) {
case 1:
printf("你选择了 1\n");
break;
case 2:
printf("你选择了 2\n");
break;
case 3:
printf("你选择了 3\n");
break;
default:
printf("无效选择\n");
break;
}
return 0;
}
输出结果为:
你选择了 2
在上述示例中,我们使用 switch 语句根据变量 choice 的值选择性地执行不同的代码块。根据 choice 的值为 2,匹配到了第二个 case 分支,因此执行了该分支下的代码块并输出结果。
需要注意的是,每个 case 分支后面都需要使用 break 关键字来结束该分支,否则程序将会继续执行下一个分支的代码块,直到遇到 break 或者 switch 结束。如果省略了 break,则会发生所谓的 "case 穿透"(case fall-through),即从匹配的 case 开始执行,一直执行到遇到下一个 case 或者 default。
在 switch 中,expression 必须是整型或字符型,而 case 中的常量值必须是整型常量或字符常量。C 语言不支持在 case 中使用浮点数或字符串。
总结来说,switch 语句提供了一种根据表达式值执行不同代码块的方式,可以替代一系列的嵌套 if-else 结构,使代码更加清晰和简洁。
注:switch 语句也是一种分支语句,常常用于多分支的情况。
case 分支的基本语法如下:
switch (expression) {
case value1:
// 当 expression 等于 value1 时执行的代码
break;
case value2:
// 当 expression 等于 value2 时执行的代码
break;
// 更多 case 分支...
default:
// 当 expression 不等于任何一个 case 值时执行的代码
break;
}
其中,value1、value2 等是常量值,可以是整型常量、字符常量或枚举常量。expression 是一个表达式,其值会依次与每个 case 的常量值进行比较。
当 expression 的值与某个 case 的常量值相等时,程序将执行该 case 下的代码块,并从该 case 处开始顺序执行后续的代码,直到遇到 break 关键字或者 switch 结束。如果省略了 break,程序将会继续执行下一个 case 分支的代码块(即发生 "case 穿透")。
如果 expression 的值与所有 case 的常量值都不相等,则会执行 default 下的代码块(如果有定义 default 分支)。
下面是一个示例,演示了开关语句中多个 case 分支的使用:
#include
int main() {
int day = 3;
switch (day) {
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
default:
printf("无效的日期\n");
break;
}
return 0;
}
输出结果为:
星期三
在上述示例中,我们使用 switch 语句根据变量 day 的值执行相应的代码块。根据 day 的值为 3,匹配到了第三个 case 分支,因此执行了该分支下的代码块并输出结果。
需要注意的是,case 分支的常量值必须是编译时可确定的常量表达式,而不能是变量或运行时的表达式。而且,在同一个 switch 语句中,各个 case 的常量值必须唯一,即不能有重复的值。
总结来说,case 是开关语句中用于定义不同分支的关键字,它根据开关表达式的值选择性地执行相应的代码块。通过合理使用 case 分支,可以根据不同的条件执行不同的代码逻辑,使程序的控制流更加灵活和清晰。
注:case 常量表达式只是起语句标号作用,并不是该处进行条件判断。在执行 switch 语句时,根据 switch 的表达式,找到与之匹配的 case 语句,就从此 case 子句执行下去,不在进行判断,直到碰到 break 或函数结束为止。
c语言中 case 是和 switch 一起使用的,构成 switch—case 语句,进行判断选择,case 是用来表示选择结构的。
在开关语句(switch 语句)中,default 关键字表示开关表达式的值没有与任何 case 分支的常量值匹配时执行的代码块。它类似于 if-else 结构中的 else 分支,用于处理除了已经具体列举的情况之外的情况。
default 分支的语法如下:
switch (expression) {
case value1:
// 当 expression 等于 value1 时执行的代码
break;
case value2:
// 当 expression 等于 value2 时执行的代码
break;
// 更多 case 分支...
default:
// 当 expression 不等于任何一个 case 值时执行的代码
break;
}
在 switch 语句中,default 分支是可选的。如果省略了 default 分支,并且开关表达式的值没有与任何 case 分支的常量值匹配,那么程序将直接跳过 switch 语句继续执行下面的代码。
通常,我们会在 default 分支中输出一条相应的提示信息,或者执行一些默认的操作。比如:
#include
int main() {
int option = 5;
switch (option) {
case 1:
printf("执行选项 1\n");
break;
case 2:
printf("执行选项 2\n");
break;
case 3:
printf("执行选项 3\n");
break;
default:
printf("无效的选项,执行默认操作\n");
break;
}
return 0;
}
输出结果为:
无效的选项,执行默认操作
在上述示例中,开关表达式 option 的值为 5,没有与任何一个 case 分支的常量值匹配。因此,程序执行了 default 分支下的代码块,输出了相应的提示信息。
需要注意的是,default 分支可以放在开关语句的任意位置,并不一定非要放在最后。不过一般习惯将 default 分支放在最后,以便于代码的阅读和理解。
总结来说,default 是开关语句中用于处理开关表达式值与所有 case 分支常量值都不匹配时的一种情况。通过定义 default 分支,我们可以提供一个针对其他情况的通用处理逻辑,从而增强程序的健壮性和容错能力。
注:default 的作用就是switch语句里所有的 case 都不成立时所要执行的语句。
default 关键字用来标记switch语句中的默认分支。
return 是用于子程序(函数或方法)中的返回语句,用于将控制流程返回给调用者,并且可以返回一个值(带参数)或不返回任何值(不带参数)。
带参数的 return 语句的基本语法如下:
return expression;
其中,expression 是可选的,表示要返回给调用者的值。它可以是常量、变量、表达式,甚至是函数调用的结果。返回值的类型必须与函数声明的返回类型相匹配。
下面是一个示例,演示了带参数的 return 语句的使用:
int square(int num) {
int result = num * num;
return result;
}
int main() {
int number = 5;
int squared = square(number);
printf("%d 的平方是 %d\n", number, squared);
return 0;
}
输出结果为:
5 的平方是 25
在上述示例中,我们定义了一个名为 square 的函数,它接收一个整数参数 num,计算 num 的平方,并通过 return 语句返回结果。在 main 函数中,我们调用了 square 函数并将返回的平方值存储到变量 squared 中,然后输出结果。
需要注意的是,一旦执行了 return 语句,该子程序的执行将立即停止,并且返回到调用者处继续执行。因此,在 return 语句之后的代码将不再执行。
另外,如果一个函数声明的返回类型是 void,表示该函数不返回任何值。那么在函数内部可以使用简单的 return 语句来提前结束函数的执行,如:
void printMessage() {
printf("Hello, World!\n");
return; // 可以省略,因为没有返回值
}
int main() {
printMessage();
return 0;
}
输出结果为:
Hello, World!
在上述示例中,printMessage 函数的返回类型是 void,所以不需要返回任何值。我们在函数内部使用了一个简单的 return 语句来提前结束函数的执行。
总结来说,return 是用于子程序中的返回语句,它可以带参数(返回值)或者不带参数。带参数的 return 语句用于将一个值返回给调用者,而不带参数的 return 语句用于提前结束函数的执行。通过合理使用 return 语句,可以实现在函数内部返回结果或者提前退出函数的控制流程。
注:return 表示把程序流程从被调函数转向主调函数并把表达式的值带回主调函数,实现函数值的返回,返回时可附带一个返回值,由 return 后面的参数指定。
注:extern 用在变量或函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。
注:用 register 声明的变量是寄存器变量,是存放在CPU的寄存器里的。而我们平时声明的变量是存放在内存中的。虽说内存的速度已经很快了,不过跟寄存器比起来还是差得远。
寄存器变量和普通变量比起来速度上的差异很大,毕竟CPU的速度远远大于内存的速度。寄存器有这么两个特点,一个是运算速度快,一个是不能取地址。
static 是一个关键字,用于声明静态变量。静态变量是一种特殊类型的变量,其生命周期与程序的整个运行周期保持一致,不同于普通的局部变量或全局变量。
在 C 语言中,使用 static 关键字声明的静态变量具有以下特点:
A.静态变量在程序执行期间只被初始化一次。即使多次调用声明了静态变量的函数,其值也只会被初始化一次,而不会被重复初始化。
B.静态变量的作用域限定在声明所在的函数、方法或代码块内部。它们对于其他函数、方法或代码块是不可见的。
C.静态变量在声明所在的函数、方法或代码块执行结束后,仍然保留其值,直到程序运行结束。
下面是一个示例,展示了如何使用 static 关键字声明静态变量:
#include
void increment() {
static int count = 0;
count++;
printf("count: %d\n", count);
}
int main() {
increment(); // count: 1
increment(); // count: 2
increment(); // count: 3
return 0;
}
以上代码中,我们在 increment 函数内部使用 static 关键字声明了一个名为 count 的静态变量,并将其初始化为 0。每次调用 increment 函数时,count 的值会自增,并输出当前的计数值。由于 count 是静态变量,它的值在不同的函数调用之间得到保留,因此每次调用 increment 函数时,都能正确地累计计数。
需要注意的是,静态变量对于其他函数是不可见的,即使在其他函数中使用相同的名称声明局部变量,它们也不会产生冲突。
总结来说,static 关键字用于声明静态变量,其在程序执行期间只被初始化一次,作用域限定在声明所在的函数、方法或代码块内部。静态变量在声明所在的函数、方法或代码块执行结束后仍然保留其值,直到程序运行结束。通过使用静态变量,我们可以在函数内部创建具有全局性质的变量,并且能够保持状态的持久性和独立性。
注:static 关键字不仅可以用来修饰变量,还可以用来修饰函数。在使用 static 关键字修饰变量时,我们称此变量为静态变量。静态变量的存储方式与全局变量一样,都是静态存储方式。静态变量属于静态存储方式,属于静态存储方式的变量却不一定就是静态变量。
const 是一个关键字,用于声明只读变量,即不可修改的变量。在 C 语言中,使用 const 关键字声明的变量在程序运行过程中不能被修改。
const 变量的特点如下:
A.const 变量在声明时必须进行初始化,并且一旦初始化后,其值就不能再被修改。
B.const 变量的值在编译时确定,并且在运行时不可改变。
C.const 变量的作用域可以是全局的(在文件范围内)或局部的(在函数、方法或代码块内)。它们对其他代码是只读的,而不仅限于声明所在的作用域。
以下是几个使用 const 关键字声明只读变量的示例:
#include
void printSize(const int length, const int width) {
// 尝试修改 const 变量将引发编译错误
// length = 10; // 错误: assignment of read-only parameter 'length'
// width = 5; // 错误: assignment of read-only parameter 'width'
printf("Size: %d x %d\n", length, width);
}
int main() {
const int MAX_VALUE = 100;
printf("Max value: %d\n", MAX_VALUE);
printSize(10, 5);
return 0;
}
上述代码中,我们使用 const 关键字声明了三个只读变量:length 和 width 是 printSize 函数的参数,分别表示长度和宽度;MAX_VALUE 是在 main 函数中声明的全局常量,表示最大值。这些变量在声明时被初始化,并且在其后的执行过程中不能被修改。
需要注意的是,const 关键字修饰的只读变量只能在声明时初始化,不能通过赋值来修改其值。
总结来说,const 是一个关键字,用于声明只读变量。const 变量在声明时必须进行初始化,并且一旦初始化后,其值就不能再被修改。它们的作用域可以是全局的或局部的,对其他代码是只读的。通过使用 const 关键字,我们可以明确表达出某些变量是只读的,增强程序的可读性和健壮性。
注:const 是 constant 的缩写,意思是“恒定不变的”!它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。
sizeof 是一个运算符,用于计算数据类型或变量在内存中所占的字节数。它可以用来获取各种数据类型的大小,包括基本类型(如整数、浮点数等)和复合类型(如结构体、数组等)。
使用 sizeof 运算符的一般语法是:
sizeof (type)
其中,type 表示你要计算大小的数据类型或变量。
以下是几个示例,展示了如何使用 sizeof 运算符来计算不同数据类型的大小:
#include
int main() {
int a;
printf("Size of int: %zu\n", sizeof(a));
char b;
printf("Size of char: %zu\n", sizeof(b));
float c;
printf("Size of float: %zu\n", sizeof(c));
double d;
printf("Size of double: %zu\n", sizeof(d));
int arr[5];
printf("Size of array: %zu\n", sizeof(arr));
struct {
int x;
char y;
float z;
} s;
printf("Size of struct: %zu\n", sizeof(s));
return 0;
}
上述代码中,我们声明了不同的变量和数据类型,并使用 sizeof 运算符打印出它们在内存中的大小(以字节为单位)。对于基本类型和数组,sizeof 运算符返回它们在内存中所占的字节数。对于结构体,sizeof 运算符返回结构体的总字节数,包括各个成员变量所占用的空间。
在输出结果中,%zu 是用于打印 sizeof 返回值的格式控制符,它对应的参数类型是 size_t。size_t 是无符号整数类型,可以容纳 sizeof 运算符的返回值。
需要注意的是,sizeof 运算符在编译时求值,而不是在运行时。因此,它可以用来获取数据类型的大小,并在程序中进行相应的内存分配和操作。
总结来说,sizeof 是一个运算符,用于计算数据类型或变量在内存中所占的字节数。它可以用来获取基本类型和复合类型的大小,并在程序中进行内存操作。
注:sizeof 的作用就是返回一个对象或者类型所占的内存字节数。返回值类型为 size_t ,在头文件stddef.h 中定义
typedef 是 C 语言中的一个关键字,用于为数据类型取别名。通过 typedef,我们可以创建用户定义的数据类型,并为其指定一个新的名称。
typedef 的一般语法如下:
typedef type new_name;
其中,type 表示你要为其取别名的数据类型,new_name 是为该数据类型指定的新名称。
以下是几个示例,展示了如何使用 typedef 来为数据类型取别名:
#include
typedef int myInt;
typedef struct {
int x;
int y;
} Point;
int main() {
myInt a = 10;
printf("a: %d\n", a);
Point p;
p.x = 5;
p.y = 3;
printf("Point: (%d, %d)\n", p.x, p.y);
return 0;
}
在上述代码中,我们使用 typedef 关键字为 int 类型取了一个别名 myInt。这样,我们就可以使用 myInt 来声明变量,而它实际上是 int 类型的别名。
同样地,我们还使用 typedef 关键字为结构体取了一个别名 Point。这样,我们可以直接使用 Point 来定义结构体变量,而不需要每次都写出完整的结构体声明。
通过使用 typedef,我们可以提高代码的可读性,并且可以更方便地使用自定义的数据类型。
需要注意的是,typedef 可以用于为任何合法的数据类型取别名,包括基本类型、指针类型、数组类型、结构体类型等。
总结来说,typedef 是一个关键字,用于为数据类型取别名。通过使用 typedef,我们可以定义和使用自定义的数据类型,并为其指定新的名称,提高代码的可读性和灵活性。
注:在C语言中,除系统定义的标准类型和用户自定义的结构体、共用体等类型之外,还可以使用类型说明语句 typedef 定义新的类型来代替已有的类型。
volatile 是 C 语言中的一个关键字,用于告诉编译器某个变量可能会被程序以外的因素更改,从而禁止编译器对该变量的一些优化操作。
当使用 volatile 关键字修饰一个变量时,编译器会将对该变量的读写操作生成真正的机器指令,而不是优化成寄存器操作。这是因为编译器默认认为变量的值在程序执行期间不会改变,可以进行一些优化,例如对变量的读取进行缓存或寄存器优化。
然而,有些变量的值可能会因为各种原因在编译器无法预测的情况下被隐含地修改,典型的例子是与硬件设备交互的寄存器、多线程共享变量等。在这种情况下,我们需要使用 volatile 关键字显式地告诉编译器不要对该变量进行优化,每次都从内存中读取到最新的值,以确保程序的正确性。
以下是一个示例,展示了如何使用 volatile 关键字:
#include
int main() {
volatile int count = 0;
while (count < 10) {
printf("Count: %d\n", count);
count++;
}
return 0;
}
在上述代码中,我们使用 volatile 关键字修饰了变量 count。这意味着每次访问 count 时,编译器都会从内存中读取最新的值,而不是使用缓存或寄存器中的旧值。
需要注意的是,volatile 关键字只是向编译器发出一个提示,告诉它该变量可能会被外部因素改变,并应该避免进行一些优化。它不会提供任何线程安全性或同步保证。如果需要确保多线程环境下的正确性,请使用适当的同步机制。
总结来说,volatile 是一个关键字,用于告诉编译器某个变量可能会被程序以外的因素更改,禁止编译器对该变量的一些优化操作。使用 volatile 可以确保每次访问变量时都从内存中读取最新的值,适用于与硬件交互的寄存器、多线程共享变量等场景。
注:volatile 是一个类型修饰符(type specifier),就像我们熟悉的 const 一样,它是被设计用来修饰被不同线程访问和修改的变量; volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。