Auc的个人博客

vuePress-theme-reco Auc    2020 - 2021
Auc的个人博客 Auc的个人博客

选择一个主题吧~

  • 暗黑
  • 自动
  • 明亮
主页
分类
  • JavaScript
  • Vue
  • 数据结构与算法
  • 文档
  • 面试题
  • 笔记
标签
笔记
  • CSS
  • ES6
  • JavaScript
  • Vue
  • C语言
文档
  • Vueのapi
  • Vue Router
  • axios
  • Vue CLI
面试
  • JS
  • Vue
  • 基础
时间线
联系我
  • GitHub (opens new window)
author-avatar

Auc

62

文章

11

标签

主页
分类
  • JavaScript
  • Vue
  • 数据结构与算法
  • 文档
  • 面试题
  • 笔记
标签
笔记
  • CSS
  • ES6
  • JavaScript
  • Vue
  • C语言
文档
  • Vueのapi
  • Vue Router
  • axios
  • Vue CLI
面试
  • JS
  • Vue
  • 基础
时间线
联系我
  • GitHub (opens new window)
  • C

    • 写在前面
    • C语言概述
    • 数据类型、运算符与表达式
    • 语句、函数、作用域与数组与字符串
    • 指针
    • 结构体
    • typedef关键字

语句、函数、作用域与数组与字符串

vuePress-theme-reco Auc    2020 - 2021

语句、函数、作用域与数组与字符串

Auc 2021-03-10 C语言笔记

# 语句、函数、作用域与数组与字符串

# 语句

# 判断语句

  1. 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 );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 循环语句

  1. while

测试循环条件 => 执行循环体 => 累加器

int main ()
{
   /* 局部变量定义 */
   int a = 10;

   /* while 循环执行 */
   while( a < 20 )
   {
      printf("a 的值: %d\n", a);
      a++;
   }
 
   return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  1. for

执行流程与 while 类似

/* for 循环执行 */
for( int a = 10; a < 20; a = a + 1 )
{
  printf("a 的值: %d\n", a);
}
1
2
3
4
5
  1. do...while

与众不同,它限制性循环体内容,再测试循环条件

/* 局部变量定义 */
int a = 10;

/* do 循环执行,在条件被测试之前至少执行一次 */
do
{
  printf("a 的值: %d\n", a);
  a = a + 1;
}while( a < 20 );
1
2
3
4
5
6
7
8
9
  1. 循环控制语句

简而言之,break 终止整个循环;continue 跳过本次循环,执行下个循环

# 函数

# 函数构成

函数头 + 函数体

/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2) 
{
   /* 局部变量声明 */
   int result;
 
   if (num1 > num2)
      result = num1;
   else
      result = num2;
 
   return result; 
}
1
2
3
4
5
6
7
8
9
10
11
12
13

以上面代码为例:

  1. 函数头:
  • 函数返回值类型: int;
  • 函数名: max;
  • 参数: 参数类型 + 参数名;
  1. 函数体: 一定别忘了返回值

# 函数声明

  • 注意参数的名称不是必须的,但是参数类型是必须的: 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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 函数参数

  1. 形式参数:

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

::: tip 注意 默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。 :::

# 作用域

  1. 在函数或块内部的局部变量;
  2. 在所有函数外部的全局变量;
  3. 在形式参数的函数参数定义中。

# 局部变量与全局变量

  1. 局部变量只能在该函数或者代码块内部使用;
  2. 全局变量便可在整个程序中使用。
#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;
}
1
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

补充

  1. 全局变量保存在内存的全局存储区中,占用静态的存储单元;
  2. 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

# 数组

# 声明数组

数组内元素类型 + 数组名[元素的数量]

int firstArray[9] 声明了一个名为 firstArray 长度为 9 的数组,并且内部数组元素都为整型。

# 初始化数组

1. 整体初始化

int firstArray[3] = {1, 45, -9}

注意

  1. 数组长度[]不可小于后面{}中的初始化元素个数;
  2. 如果省略掉[]中的长度,右面{}中的元素个数变为长度;
  3. 如果只给部分元素赋值,那么余下的元素自动初始化为 0。见下例
int arr[5] = { 1, 3, 5 };
for (int i = 0; i < 5; i++) {
  printf("arr[%d] = %d\n", i, arr[i]);
}
1
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]);
	}
}
1
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]);
		}
	}
}
1
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' };  //对全体元素赋值时可以省去长度
1
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";
1
2
3
4
5

注意

  1. 这几种方式都可以声明字符串;
  2. 字符数组(字符串)只有在定义时才可以将整个字符串一次性初始化,一旦定义完了,就只能一个字符一个字符地赋值了。如下:
char str[3];
str = "the" // 错误

// 一点定义后想改变只能一个个赋值
str[0] = 't';
str[1] = 'h';
str[2] = 'e';
1
2
3
4
5
6
7

# 字符串结束的标志

字符串以\0作为结束的标志

在C语言中,字符串总是以'\0'作为结尾,所以'\0'也被称为字符串结束标志,或者字符串结束符。

解释

'\0'是 ASCII 码表中的第 0 个字符,英文称为 NUL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在C语言中唯一的作用就是作为字符串结束标志。

解析过程

  1. 由" "包围的字符串会自动在末尾添加'\0'。例如,"abc123"从表面看起来只包含了 6 个字符,其实不然,C语言会在最后隐式地添加一个'\0'。

  2. C语言在处理字符串时,会从前往后逐个扫描字符,一旦遇到'\0'就认为到达了字符串的末尾,就结束处理。'\0'至关重要,没有'\0'就意味着永远也到达不了字符串的结尾

特别注意 在声明并初始化字符串时,要时刻注意给 \0 留一个位置,也就是说字符数组的长度要比字符串实际本身长度多出 1,用来留给程序自动在末尾添加 \0

// 逐个字符地给数组赋值并不会自动添加'\0'
char str[] = { 'a', 'b', 'c' };
// 改为
char str[4] = { 'a', 'b', 'c' };

// 直接给字符串时,也要留出一个空位出来
char str[7] = "abc123";
1
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);
}
1
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);
}
1
2
3
4
5
6
7
8
9