# 语句、函数、作用域与数组与字符串
# 语句
# 判断语句
if; if...else; if...else if...else; switch
/* 局部变量定义 */
char grade = 'B';
switch(grade)
{
case 'A' :
printf("很棒!\n" );
break;
case 'B' :
case 'C' :
printf("做得好\n" );
break;
case 'D' :
printf("您通过了\n" );
break;
case 'F' :
printf("最好再试一下\n" );
break;
default :
printf("无效的成绩\n" );
}
printf("您的成绩是 %c\n", grade );
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 循环语句
- while
测试循环条件 => 执行循环体 => 累加器
int main ()
{
/* 局部变量定义 */
int a = 10;
/* while 循环执行 */
while( a < 20 )
{
printf("a 的值: %d\n", a);
a++;
}
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
- for
执行流程与 while
类似
/* for 循环执行 */
for( int a = 10; a < 20; a = a + 1 )
{
printf("a 的值: %d\n", a);
}
2
3
4
5
- do...while
与众不同,它限制性循环体内容,再测试循环条件
/* 局部变量定义 */
int a = 10;
/* do 循环执行,在条件被测试之前至少执行一次 */
do
{
printf("a 的值: %d\n", a);
a = a + 1;
}while( a < 20 );
2
3
4
5
6
7
8
9
- 循环控制语句
简而言之,break
终止整个循环;continue
跳过本次循环,执行下个循环
# 函数
# 函数构成
函数头 + 函数体
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2)
{
/* 局部变量声明 */
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
2
3
4
5
6
7
8
9
10
11
12
13
以上面代码为例:
- 函数头:
- 函数返回值类型:
int
; - 函数名:
max
; - 参数: 参数类型 + 参数名;
- 函数体: 一定别忘了返回值
# 函数声明
- 注意参数的名称不是必须的,但是参数类型是必须的:
int max(int int)
; - 函数声明是必需的。应该在调用函数的文件顶部声明函数。
# 调用函数
#include <stdio.h>
/* 函数声明 */
int getMaxNumber(int num1, int num2);
int main(void)
{
int a = 23, b = 234;
int result = getMaxNumber(a, b);
printf("a = %d, b = %d\n", a, b);
printf("The max value is: %d", result);
}
/* 函数返回两个数中较大的那个数 */
int getMaxNumber(int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 函数参数
- 形式参数:
如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

# 作用域
- 在函数或块内部的局部变量;
- 在所有函数外部的全局变量;
- 在形式参数的函数参数定义中。
# 局部变量与全局变量
- 局部变量只能在该函数或者代码块内部使用;
- 全局变量便可在整个程序中使用。
#include <stdio.h>
/* 全局变量声明 */
int g;
int main ()
{
/* 局部变量声明 */
int a, b;
/* 实际初始化 */
a = 10;
b = 20;
g = a + b;
printf ("value of a = %d, b = %d and g = %d\n", a, b, g);
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 形式参数
形式参数被当作该函数内的局部变量,如果与全局变量同名它们会优先使用
#include <stdio.h>
/* 全局变量声明 */
int a = 20;
int main ()
{
/* 在主函数中的局部变量声明 */
int a = 10;
int b = 22;
int sum(int, int);
return 0;
}
/* 添加两个整数的函数 */
int sum(int a, int b)
{
return a + b;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
补充
- 全局变量保存在内存的全局存储区中,占用静态的存储单元;
- 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
# 数组
# 声明数组
数组内元素类型 + 数组名[元素的数量]
int firstArray[9]
声明了一个名为 firstArray 长度为 9 的数组,并且内部数组元素都为整型。
# 初始化数组
1. 整体初始化
int firstArray[3] = {1, 45, -9}
注意
- 数组长度[]不可小于后面{}中的初始化元素个数;
- 如果省略掉[]中的长度,右面{}中的元素个数变为长度;
- 如果只给部分元素赋值,那么余下的元素自动初始化为 0。见下例
int arr[5] = { 1, 3, 5 };
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
2
3
4
打印结果:

比如:
当赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0:
- 对于short、int、long,就是整数 0;
- 对于char,就是字符 '\0';
- 对于float、double,就是小数 0.0。
2. 使用循环语句一个个初始化
3. 为数组中的指定索引的元素赋值
firstArray[2] = 78
给数组中索引为2的元素赋值为78
# 访问数组元素
使用索引值来访问数组中指定元素: int value = firstArray[8]
表示将数组中索引为8的元素的值赋给新变量。
小例子:
#include <stdio.h>
int main(void)
{
int numberArr[10];
int i, j;
for (i = 0; i < 10; i++) {
numberArr[i] = i + 1 + 100;
}
for (j = 0; j < 10; j++) {
printf("numberArr[%d] = %d\n", j+1, numberArr[j]);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 多维数组
int threeArr[2][3][2]
定义了一个三维整型数组。
二维数组初始化与遍历
#include <stdio.h>
int main()
{
/*初始化二维数组*/
int doubleArr[3][2] = { {1, 2}, {45, -56}, {78, 4546} };
int i, j;
/*遍历二维数组*/
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("doubleArr[%d][%d] = %d\n", i + 1, j + 1, doubleArr[i][j]);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 其他补充
学完指针回来补充

# 字符串
# 字符数组
用来存放字符的数组称为字符数组
char a[10]; //一维字符数组
char b[5][10]; //二维字符数组
char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 给部分数组元素赋值
char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' }; //对全体元素赋值时可以省去长度
2
3
4
字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。
# 声明并初始化字符串
char str[4] = {'w', 'i', 'n'};
char str1[4] = {"win"};
char str2[4] = "win";
char str3[] = {"win"};
char str4[] = "win";
2
3
4
5
注意
- 这几种方式都可以声明字符串;
- 字符数组(字符串)只有在定义时才可以将整个字符串一次性初始化,一旦定义完了,就只能一个字符一个字符地赋值了。如下:
char str[3];
str = "the" // 错误
// 一点定义后想改变只能一个个赋值
str[0] = 't';
str[1] = 'h';
str[2] = 'e';
2
3
4
5
6
7
# 字符串结束的标志
字符串以\0
作为结束的标志
在C语言中,字符串总是以'\0'作为结尾,所以'\0'也被称为字符串结束标志,或者字符串结束符。
解释
'\0'是 ASCII 码表中的第 0 个字符,英文称为 NUL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在C语言中唯一的作用就是作为字符串结束标志。
解析过程
由" "包围的字符串会自动在末尾添加'\0'。例如,"abc123"从表面看起来只包含了 6 个字符,其实不然,C语言会在最后隐式地添加一个'\0'。
C语言在处理字符串时,会从前往后逐个扫描字符,一旦遇到'\0'就认为到达了字符串的末尾,就结束处理。'\0'至关重要,没有'\0'就意味着永远也到达不了字符串的结尾

特别注意
在声明并初始化字符串时,要时刻注意给 \0
留一个位置,也就是说字符数组的长度要比字符串实际本身长度多出 1,用来留给程序自动在末尾添加 \0
// 逐个字符地给数组赋值并不会自动添加'\0'
char str[] = { 'a', 'b', 'c' };
// 改为
char str[4] = { 'a', 'b', 'c' };
// 直接给字符串时,也要留出一个空位出来
char str[7] = "abc123";
2
3
4
5
6
7
练习
将 26 个大写英文字符存入字符数组,并以字符串的形式输出
#include <stdio.h>
// 需求:将 26 个大写英文字符存入字符数组,并以字符串的形式输出
int main()
{
// 先将数组初始化,因为为字符数组,所以右边的 0,按ASCII码解析成 '\0'
// 又因为数组的特性,如果只初始化部分数组元素,那么剩余的数组元素也会自动初始化为“零”值,详见数组小节
// 这样,每一位都先被初始化为了 '\0',最后留出来的终止位自然也是 '\0',就不用理会了。
char str[27] = { 0 };
char c;
int i;
// 因为 c 也为char型,所以 65,90 也是按ASCII码解析,对应A与Z
for (c = 65, i = 0; c <= 90; c++, i++) {
str[i] = c;
}
printf("%s\n", str);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 字符串长度
字符串的长度就是字符串包含了多少个字符(不包括最后的结束符'\0')
在C语言中,我们使用 string.h
头文件中的 strlen()
函数来求字符串的长度
#include <stdio.h>
#include <string.h>
int main()
{
char thisString[] = "this is a test message.";
long length = strlen(thisString);
printf("The length of thisString is: %ld.\n", length);
}
2
3
4
5
6
7
8
9