[C.C++] 【C语言】第一章:从变量到数组

24 0
Honkers 3 小时前 | 显示全部楼层 |阅读模式

系列说明:在学习阶段我就开始着手C语言的笔记并发表博客,本文是对我学习阶段C语言笔记的整理归纳,希望和大家共同进步。什么地方有遗漏欢迎大家指出。

运行环境:本系列所有演示代码均在 Visual Studio 2022(x64)环境下编写。

目录

    1. 初识C语言:hello world 与开发环境
    1. 数据类型
    1. 变量与常量
    1. 输入输出:printf / scanf
    1. 操作符
    1. 分支与循环
    1. 数组
    1. 本章小结

正文

1. 初识C语言:hello world 与开发环境

C语言是一门面向过程的编程语言,main 函数是程序的入口,程序总是从 main 函数开始执行。在 VS2022 中新建"空项目",添加 .c 源文件后即可编写代码。

demo1_第一个C程序

  1. //第一个C程序:hello world
  2. #include <stdio.h>
  3. int main()
  4. {
  5. // 在屏幕上打印一行文字
  6. printf("hello world\n");
  7. return 0;
  8. }
复制代码

预期终端输出

  1. hello world
复制代码

说明:

  • #include 是"标准输入输出"头文件,printf 的声明在其中。
  • \n 是换行转义字符。
  • return 0; 表示程序正常结束。

2. 数据类型

C语言为不同类型的数据提供了不同的类型,数据类型决定了数据的大小与含义。

类型大小(64位VS2022)说明
char1 字节字符型,也可存储小整数
short2 字节短整型
int4 字节整型
long4 字节长整型(VS中与int相同)
long long8 字节更长的整型
float4 字节单精度浮点型
double8 字节双精度浮点型

sizeof 是操作符(不是函数),用来计算一个类型或变量所占内存大小,返回 size_t 类型,用 %zu 打印。由于 sizeof 是操作符,括号内的表达式不会被执行

demo2_sizeof.c —— 计算各类型大小

  1. // demo2_sizeof.c - sizeof计算各数据类型大小(单位:字节)
  2. #include <stdio.h>
  3. int main()
  4. {
  5. // sizeof 是操作符,返回 size_t 类型,用 %zu 打印
  6. printf("char = %zu\n", sizeof(char));
  7. printf("short = %zu\n", sizeof(short));
  8. printf("int = %zu\n", sizeof(int));
  9. printf("long = %zu\n", sizeof(long));
  10. printf("long long = %zu\n", sizeof(long long));
  11. printf("float = %zu\n", sizeof(float));
  12. printf("double = %zu\n", sizeof(double));
  13. return 0;
  14. }
复制代码

预期终端输出

  1. char = 1
  2. short = 2
  3. int = 4
  4. long = 4
  5. long long = 8
  6. float = 4
  7. double = 8
复制代码

3. 变量与常量

C语言中,经常变化的值称为变量,不变的值称为常量。变量在定义时需指定数据类型。

3.1 全局变量与局部变量
  • 局部变量:在大括号内部定义的变量,作用域为所在的局部范围,进入作用域创建、出作用域销毁。
  • 全局变量:在大括号外部定义的变量,作用域为整个工程,生命周期与程序一致。

当局部变量与全局变量同名时,局部变量优先使用

demo3_variable.c —— 变量的分类与作用域

  1. // demo3_variable.c - 全局变量与局部变量、作用域、生命周期
  2. #include <stdio.h>
  3. int global = 300; // 全局变量:在函数外部定义,作用于整个工程
  4. int main()
  5. {
  6. int local = 200; // 局部变量:在函数内部定义
  7. // 局部变量与全局变量同名时,局部变量优先使用
  8. int global = 100;
  9. printf("local = %d\n", local);
  10. printf("global = %d\n", global);
  11. return 0;
  12. }
复制代码

预期终端输出

  1. local = 200
  2. global = 100
复制代码

3.2 内存区域

一般我们会关注内存中的三个区域:

  • 栈区:存放局部变量(进入作用域创建,出作用域销毁)。
  • 堆区:用于动态内存管理(后续文章详解)。
  • 静态区:存放全局变量和 static 修饰的变量。

4. 输入输出:printf / scanf

4.1 printf 函数

printf 是格式化输出函数,使用 % 加占位符来格式化输出。

占位符含义
%d整型
%f / %lffloat / double
%c字符
%s字符串
%zusize_t 类型
%p地址
%%打印百分号
%5d最少5位,不足左侧补空格
%-5d最少5位,不足右侧补空格
%.2f保留2位小数
\n \t \\ \" \'换行、制表、反斜杠、双引号、单引号转义

printf 的返回值是打印成功的字符个数

demo4_printf.c —— 占位符与转义字符

  1. // demo4_printf.c - printf 占位符与转义字符
  2. #include <stdio.h>
  3. int main()
  4. {
  5. int n = 456;
  6. double d = 3.14159;
  7. // 基本占位符
  8. printf("%d\n", n); // 整型
  9. printf("%.2f\n", d); // 浮点型保留2位小数
  10. printf("%5d\n", n); // 最少5位,不足左侧补空格
  11. printf("%-5d|\n", n); // 最少5位,不足右侧补空格
  12. printf("%%d\n"); // 打印百分号
  13. printf("Tab:\tHi\n"); // 制表符
  14. printf("C:\\temp\n"); // 反斜杠转义
  15. // printf 的返回值是打印的字符个数(链式)
  16. printf("%d\n", printf("%d\n", printf("%d\n", n)));
  17. return 0;
  18. }
复制代码

预期终端输出

  1. 456
  2. 3.14
  3. 456
  4. 456 |
  5. %d
  6. Tab: Hi
  7. C:\temp
  8. 456
  9. 4
  10. 2
复制代码

4.2 scanf 函数

scanf 是格式化输入函数。注意:scanf 需要把输入存放到地址中,所以基本类型变量前要加取地址符 &(数组名本身就是地址,不加 &)。

scanf 的返回值是成功读取的数据个数;读取错误或遇到文件结尾返回 EOF。

demo5_scanf.c —— scanf 基本用法与返回值

  1. // demo5_scanf.c - scanf 基本用法与返回值
  2. #define _CRT_SECURE_NO_WARNINGS 1 // vs2022中使用scanf需要添加这一行代码
  3. #include <stdio.h>
  4. int main()
  5. {
  6. int a = 0;
  7. int b = 0;
  8. char ch = 0;
  9. char str[20] = { 0 };
  10. // 输入两个整数
  11. printf("请输入两个整数: ");
  12. int ret = scanf("%d %d", &a, &b);
  13. printf("成功读取个数 = %d, a = %d, b = %d\n", ret, a, b);
  14. // 读取单个字符(前面加一个空格跳过空白字符)
  15. printf("请输入一个字符: ");
  16. scanf(" %c", &ch);
  17. printf("ch = %c\n", ch);
  18. // 读取一行字符串(读到换行停止,用于含空格的字符串)
  19. // 注意:%c 读取后缓冲区残留换行,%[^\n] 前加空格可跳过空白
  20. printf("请输入一行字符串: ");
  21. scanf(" %[^\n]s", str);
  22. printf("str = %s\n", str);
  23. return 0;
  24. }
复制代码

预期终端输出(键盘依次输入 10 20、A、hello world):

  1. 请输入两个整数: 成功读取个数 = 2, a = 10, b = 20
  2. 请输入一个字符: ch = A
  3. 请输入一行字符串: str = hello world
复制代码

说明:scanf(" %c", &ch) 中 %c 前的空格用于跳过输入缓冲区中残留的空白字符(如换行),这是读取字符时的常见处理。

5. 操作符

5.1 算术操作符:+ - * / %
  • /:两端都是整数时执行整数除法(取商),至少一个为浮点数时执行浮点除法。
  • %:取模(求余)运算,只能用于整数;结果符号由第一个操作数决定。
5.2 赋值操作符与复合赋值
  • 创建变量时给值叫初始化,之后给值叫赋值
  • 复合赋值:a += 3 等价于 a = a + 3,-= *= /= %= 同理。
5.3 自增自减
  • a++:后置,先使用再自增。
  • ++a:前置,先自增再使用。
  • a--、--a 同理。
5.4 关系操作符

== >= > < <=:符合返回1,不符合返回0。

5.5 逻辑操作符
  • &&:逻辑与。左侧为0时短路,右侧不执行。
  • ||:逻辑或。左侧非0时短路,右侧不执行。
  • !:逻辑取反。
5.6 条件操作符(三目)

表达式1 ? 表达式2 : 表达式3:表达式1为真执行2,为假执行3。

demo6_operator.c —— 常见操作符

  1. // demo6_operator.c - 常见操作符:算术、赋值、自增自减、逻辑短路
  2. #include <stdio.h>
  3. int main()
  4. {
  5. // 算术操作符:整数除法与浮点除法
  6. float x = 6 / 4; // 两端都是整数 => 整数除法,商为1
  7. float y = 6.0 / 4; // 至少一个浮点数 => 浮点除法
  8. printf("6/4 = %.1f\n", x);
  9. printf("6.0/4 = %.1f\n", y);
  10. // 取模运算,结果的符号由第一个操作数决定
  11. printf("11%%-5 = %d\n", 11 % -5);
  12. printf("-11%%5 = %d\n", -11 % 5);
  13. // 自增自减:前置先自增再使用,后置先使用再自增
  14. int a = 5;
  15. int b = a++; // b=5, a=6
  16. printf("b=a++ => b=%d, a=%d\n", b, a);
  17. int c = 5;
  18. int d = ++c; // d=6, c=6
  19. printf("d=++c => d=%d, c=%d\n", d, c);
  20. // 逻辑短路:&& 左侧为0,右侧不执行
  21. int i = 0;
  22. int ret = (0 && ++i); // ++i 被短路,不执行
  23. printf("短路后 i = %d, ret = %d\n", i, ret);
  24. return 0;
  25. }
复制代码

预期终端输出

  1. 6/4 = 1.0
  2. 6.0/4 = 1.5
  3. 11%-5 = 1
  4. -11%5 = -1
  5. b=a++ => b=5, a=6
  6. d=++c => d=6, c=6
  7. 短路后 i = 0, ret = 0
复制代码

6. 分支与循环

C语言是结构化程序设计语言,所有逻辑可拆解为顺序、选择、循环三种结构的组合。

6.1 if 语句

if 根据表达式的"真/假"(0为假,非0为真)决定是否执行。控制多条语句必须用大括号 {}

6.2 switch 语句

switch 用于"多值匹配",表达式必须是整型,case 后必须是整型常量。case 具有穿透性,需用 break 终止;default 处理所有不匹配的情况。

6.3 循环
  • while:先判断后执行,适合循环次数不确定的场景。
  • for:将"初始化、判断、调整"集中一处,最常用。
  • do-while:至少执行一次
  • break:终止循环;continue:跳过本次循环剩余代码,进入下一次。
  • goto:快速跳转,能不用尽量不用(多层循环跳出除外)。

demo7_loop.c —— 分支与循环综合

  1. // demo7_loop.c - 分支与循环综合:3的倍数之和、质数判断、多组输入
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include <stdio.h>
  4. int main()
  5. {
  6. // 1. 计算 1~100 中 3 的倍数之和
  7. int sum = 0;
  8. for (int i = 3; i <= 100; i += 3)
  9. {
  10. sum += i;
  11. }
  12. printf("3的倍数之和 = %d\n", sum);
  13. // 2. 判断一个正整数是否为质数
  14. int n = 0;
  15. printf("请输入一个正整数: ");
  16. scanf("%d", &n);
  17. int flag = 1; // 假设是质数
  18. for (int i = 2; i < n; i++)
  19. {
  20. if (n % i == 0)
  21. {
  22. flag = 0; // 能整除则不是质数
  23. break;
  24. }
  25. }
  26. if (flag && n > 1)
  27. printf("%d 是质数\n", n);
  28. else
  29. printf("%d 不是质数\n", n);
  30. // 3. 多组输入:读到文件结尾(EOF)为止
  31. int m = 0;
  32. int cnt = 0;
  33. while (scanf("%d", &m) != EOF)
  34. {
  35. cnt++;
  36. }
  37. printf("共读取 %d 个整数\n", cnt);
  38. return 0;
  39. }
复制代码

预期终端输出(键盘输入 7,再输入 5 6 7 8 后按 Ctrl+Z 结束):

  1. 3的倍数之和 = 1683
  2. 请输入一个正整数: 7 是质数
  3. 共读取 4 个整数
复制代码

7. 数组

数组是一类相同类型元素的集合。

7.1 一维数组

定义:类型 数组名[常量],例如 int arr[5];

初始化

  1. int arr1[10] = {1,2,3,4,5,6,7,8,9,10}; // 完全初始化
  2. int arr2[10] = {0}; // 不完全初始化,其余补0
  3. int arr3[] = {1,2,3}; // 省略长度,由初始化列表决定
复制代码

访问:下标从0开始,arr 访问第 i 个元素。

元素个数:int sz = sizeof(arr) / sizeof(arr[0]);

特点:数组元素在内存中连续存放

7.2 二维数组
  • 把一维数组作为数组的元素,就构成二维数组,即"数组的数组"。
  • 初始化:先存满一行再存下一行;分行初始化用 {};可以省略行数,但不能省略列数
  • 二维数组元素在内存中也是连续存放的(按行)。

demo8_array.c —— 一维与二维数组

  1. // demo8_array.c - 一维与二维数组:定义、访问、内存连续存放、元素个数
  2. #include <stdio.h>
  3. int main()
  4. {
  5. // 一维数组:完全初始化 / 不完全初始化 / 省略长度
  6. int arr1[5] = { 1, 2, 3, 4, 5 };
  7. int arr2[5] = { 1, 2 }; // 其余补0
  8. int arr3[] = { 1, 2, 3 }; // 由初始化列表决定长度3
  9. // 计算元素个数
  10. int sz = sizeof(arr1) / sizeof(arr1[0]);
  11. printf("arr1 元素个数 = %d\n", sz);
  12. // 打印一维数组元素及其地址(连续存放)
  13. printf("arr1 的地址: %p\n", arr1);
  14. for (int i = 0; i < 5; i++)
  15. {
  16. printf("&arr1[%d] = %p\n", i, &arr1[i]);
  17. }
  18. // 二维数组:分行初始化
  19. int matrix[3][5] = { {1, 2}, {3, 4, 5}, {6, 7} };
  20. printf("二维数组打印:\n");
  21. for (int i = 0; i < 3; i++)
  22. {
  23. for (int j = 0; j < 5; j++)
  24. {
  25. printf("%d ", matrix[i][j]);
  26. }
  27. printf("\n");
  28. }
  29. return 0;
  30. }
复制代码

预期终端输出(地址数值每次运行可能不同,间隔规律相同):

  1. arr1 元素个数 = 5
  2. arr1 的地址: 00000057FB4FFB30
  3. &arr1[0] = 00000057FB4FFB30
  4. &arr1[1] = 00000057FB4FFB34
  5. &arr1[2] = 00000057FB4FFB38
  6. &arr1[3] = 00000057FB4FFB3C
  7. &arr1[4] = 00000057FB4FFB40
  8. 二维数组打印:
  9. 1 2 0 0 0
  10. 3 4 5 0 0
  11. 6 7 0 0 0
复制代码

变长数组:C99 支持 int arr[n];(n为变量),但 VS2022 内置编译器暂不支持变长数组,需用常量指定数组大小。

8. 本章小结

本章介绍了C语言的基础:

  • 数据类型:char / short / int / long / long long / float / double ,sizeof 用于计算大小。
  • 变量与常量:全局/局部变量、作用域、生命周期、内存三大区域。
  • 输入输出:printf 占位符与返回值、scanf 取地址与返回值。
  • 操作符:算术 / 赋值 / 自增自减 / 关系 / 逻辑 / 条件操作符。
  • 分支与循环:if / switch、for / while / do-while、break / continue。
  • 数组:一维/二维数组定义、初始化、连续存放、元素个数计算。

声明:本文为个人学习笔记,基于笔者学习内容整理,代码均在 VS2022 环境验证通过。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行