首页
关于 About
网站安全性 Security
Search
1
Chrome/Chromium 在 Linux 平台的视频硬解方案(含NVIDIA)
2,200 阅读
2
解决 Windows 11 提示“此模块被拒绝加载到本地安全机构”
1,236 阅读
3
关闭 Intel VMD 解决 INACCESSIBLE_BOOT_DEVICE 蓝屏
522 阅读
4
新版本 Chrome 122+ 关闭安全提示、扫描
408 阅读
5
连接 USB 设备到 WSL2
381 阅读
数字安全
教程
公告
默认
高通设备开发
Rockchip 设备开发
Windows
Android
Python
C 语言
登录
Search
标签搜索
Linux
Windows
Qualcomm
QCS8250
SM8250
高通
Android
Chrome
Chromium
AppArmor
PKI
OpenWrt
NVIDIA
CertificateTransparency
X509
Python
pip
Docker
Electron
WSL
日暮清林 Levi Marvin
累计撰写
25
篇文章
累计收到
12
条评论
首页
栏目
数字安全
教程
公告
默认
高通设备开发
Rockchip 设备开发
Windows
Android
Python
C 语言
页面
关于 About
网站安全性 Security
搜索到
1
篇与
的结果
2025-08-04
大学生期末必备!0基础快速入门C语言程序设计
C 语言零基础入门教程(基础版)版本:2025/08/04前言本来写这篇教程是为了期末周教一下室友,后面觉得也可以拿出来放到网上。本人只是一个业余 C 语言程序员,非专业 C 语言程序设计教师,亦无相关比赛参赛经验,文章内容有误还请指出。本文不涉及指针、数据结构相关内容(因为我的大学 C 语言程序设计课程也不考这些)。硬件基础键盘SHIFT:切换(上档),打出印有两行文字的按键中,上面一行文字的按键。CTRL:控制键,常与其他字母组合成快捷键。如复制Ctrl + C、粘贴Ctrl + V等。CAPS LOCK:大写锁定,按下后字母键均打出大写字母。TAB:缩进,自动添加四个空格或制表符,使得文字显示可以对齐。HOME:跳转到行首。END:跳转到行尾。操作系统基础所有的 C 语言程序必须有 main() 函数。操作系统在执行程序时,始终从 main 函数开始执行。程序结束后,必须给操作系统返回一个状态值,操作系统以此判断程序是否正常运行/退出。main函数是所有 C 语言程序的入口点,其函数一般以return+返回值结尾,用于向系统返回一个状态值。若使用return 0;代表程序正常退出(正常执行完毕),所有非0的返回值,代表程序出现故障,非零返回值的具体含义只有编写代码的人才知道,但操作系统知道“非0返回值代表程序运行出了问题”这个共识。计算机是无法直接运行程序的“源代码”的,源代码需要被“编译器”编译后,链接生成可以由计算机运行的“机器码”。这是高级编程语言的特性。全角字符和半角字符,中英文输入:中文的字符,!?“” —— 都是全角字符。英文的字符,! ? "" - 都是半角字符。C 语言程序代码中应当使用半角字符。操作系统的文件通常由两部分组成:文件名(Filename)和后缀(Suffix)。部分 Windows 系统会默认开启“隐藏已知文件的扩展名”(这里的扩展名就是文件后最)。文件后缀通常用以区分文件的类型。如.txt是文本文件,.xlsx是 Excel 表格,.mp3 是 MP3 格式音频文件,.h 是C/C++ 语言头文件等。C or C++什么是 C 语言,什么是 C++ 语言?顾名思义 C++ 与 C 相比,后面多了两个“++”,一看就更高级。从事实上来讲也确实如此。C 语言是面向过程的编程语言,程序设计的核心思想是“分步”,依次(按照时序图)实现所有需要的操作。C++ 语言是面向对象的编程语言,程序设计的核心思想是“对象”,可以使用“对象”支持的特性(如“多态”、“继承”等),通过将所需功能的实现载体抽象为许多不同的对象,实现对象间的操作,来实现程序的功能。比如在经典案例“学生管理系统”中,将“学生”抽象为Student对象,给这个对象实现了名字(name)、学号(number)、年级(year)等属性(变量),并实现对这些属性(变量)的操作。C++ 是兼容 C 语言的,但 C 语言不能使用 C++ 语言的代码。C 语言程序源文件通常以.c结尾,C++ 语言程序源文件通常以.cpp结尾。进制 —— 二进制、八进制、十进制、十六进制“进制” —— 一个数,不只有一位。例如在十进制中,我们有个位、十位、百位、千位...十进制的 1763日常生活中使用的是十进制,即满十进一,例如:10 + 10 = 209 + 1 = 1019 + 1 = 20二进制即为满二进一,例如:1 + 1 = 10 (不是十,十一零)0 + 1 = 110 + 1 = 11 (不是十一,是一一)11 + 1 = 100 (不是一百,是一零零)十六进制即为满十六进一,十六进制引入了字母来表示从 10 到 15 的“数”。即:0 1 2 3 4 5 6 7 8 9 a b c d e f。对应关系:DecHex0011223344556677889910a11b12c13d14e15f0x后跟十六进制数。 十进制 十六进制 十位 个位 十位 个位 0 9 0 f + ----------------------- 0 1 0 f 10 0x1eASCII(美国信息交换标准代码)ASCII(或习惯称“ASCII码”)为美国信息交换标准代码,ASCII码的第32~126为可读字符。也就是说我们的数字(可读字符形式)、字母(大写和小写)、符号(如感叹号、问号、警号、与号、星号等)都有一个唯一对应的数字(十进制、十六进制)来表示,这些“字符”可以和其唯一对应的数字相互转换。字符 十进制ASCII码0 48A 65a 97命名在 C 语言中,我们会遇到很多命名,变量的命名、函数的命名。C 语言编程中,所有的名字都是严格区分大小写的。例如 Abc 和 abc 和 abC,他们三个指代不同的东西。命名需要遵守命名规范。即:名称允许包含大小写英文字母和阿拉伯数字(不建议使用中文)和下划线,但是有条件:名称不得以数字开头,允许下划线开头;名称不得出现允许字符之外的字符(即只允许出现上述规定的字符);名称不得与 C 语言中现存“关键字”重复;一个变量/函数只能有一个“唯一的”名字,同一个名字不得重复使用。关键字:const/int/char/float/auto/register/extern/if/while...int a_b; int 0ac; // 错误 int Ab0; int _0a; int _; int Aiojsdajio; int a91ja; int const; // 错误 int inta; int int_jioa; int _int; int Abc = 0; int ABC= 0; int Abc =0; // 错误,不得与已定义变量名重复 变量变量的实质,是操作系统,根据变量的类型(所占的内存空间大小)向内存中分配一块恒定大小的内存空间区域,随后变量指向该内存区域的地址。使用变量的过程就是向该地址读写数据。基本数据类型int 整型:正整数、负整数、0short 短long 长long longlong long long...float 实型(单精度浮点型):精度为小数点后六(或七)位,多的位数会四舍五入到最后一位精度。double 实型(双精度浮点型):精度为小数点后十五位,多的位数会四舍五入到最后一位精度。char 字符型:单个字符void 无/空类型(特殊)注:使用prinf()函数%f/%lf输出时,float 和 double 默认保留 6 位小数,不足 6 位,以 0 补齐,超出则第 6 位会进行四舍五入。注:字符串必须用双引号包裹。char A = 'A'; char a = 'a'; char nihao = 'nihao'; // 错误 char A = "A"; // 可能错误 char *A = "A"; char *nihao = "Hello"; // 字符串(指针类型) char nihao[5] = "Hello"; // 字符串(数组类型) char nihao[5] = {'H', 'e', 'l', 'l', 'o'}; // 字符串(数组类型)变量的定义(存储类型) 数据类型 变量名 = 变量值(与类型匹配或支持类型转换);通常存储类型可以省略不写,不写则默认为auto(代表“动态变量”)。而存储类型表示变量的存储方式和位置。全局变量为static静态变量。如:int ZERO = 0; char A = 'A'; register int zero = 0; // 寄存器类型,变量会直接存储在 CPU 的寄存器中 static int _O = 'O'; // 静态类型,即使函数的生命周期结束,变量也不会被消失,且保留原值变量的初始化变量的初始化有两种方式:定义时赋值和先定义,后赋值(编译器会用默认值初始化)。int A = 0;int A; // 部分编译器会默认 A = 0 int main() { A = 1; // 此处对 A 人为赋值 return A; } 变量的赋值变量可以直接被赋值为固定值:int A = 100;也可以被赋值为某个函数的返回值:int _function() { return 333; } int main() { int A = _function(); printf("%d\n", A); return 0; }常量常量即长时间存在的量,不会改变,也不能改变,通常伴随整个程序或函数定义域内的生命周期。常量,我们用关键词const修饰,被const修饰的“变量”为不得修改的常量。常量的初始化必须在定义时进行。类型转换C 语言中,有很多不同的数据类型,比如整型、实型、字符型,实型甚至都分单精度浮点型和双精度浮点型。同时,我们还可以指定整型、实型、字符型变量有无“符号”(也就是是否能表示负数)。类型转换过程中,需要注意的核心要点是:数据精度和类型的兼容性。int A = 1; float B = 0.013f; int main() { // 第一种: B = A; // B 不是 1,是 1.0 // A 是整型int变量,B是实型float变量。转换过程精度增加。 // 第二种: A = B; // 精度减小。 } float A = 0.0000004f; double B = 0.0000000000013f; int main() { // 第一种: B = A; // 0.00000040000000... // 第二种: A = B; // 0.0 } float A = 0.0000004f; double B = 0.0000000000013f; int main() { // 第一种: B = A; // 0.00000040000000... // 第二种: A = B; // 0.0 } int main() { char A = 'A'; unsigned char result; result = A; }int main() { int a = -20000; unsigned int result; result = a; }数组数组:一组数据。数组取值时,需要用“数组下标”(又称“索引”)来去出数组中对应位数的数据。一维数组数据类型 数组名字[数组大小] = {数组的数据}数组大小:数组内元素的个数。数组的数据:数组内的数据,是由一个一个分开的单独的、独立的数据组成的。一组独立的数据构成数组。独立的数据类型应当与数组的数据类型一致。用逗号区分独立的数据。int asd[5] = {1, 2, 3, 4, 5}; // 取“3”值: asd[2]; int asd[5] = {1,2,3,4,5}; float dsa[2] = { 2.1, 3.4 };二维数组数据类型 数组名字[一维数组的个数][一维数组数据大小] = {数组的数据}int asd[4][5]; // 第九个元素 asd[a][b] a=1 b=3 // 0: 4 (5个) // 1: 3 (4个) // asd[1][3]生命周期 与 定义域int A = 0; // A 变脸的定义域/生命周期,是“全局”(GLOBAL) int f1() { int j = -1; // 定义域/生命周期仅限在f1函数内部。 for (int t = 2; t < 10; ++t) { // t 变量的定义域/生命周期仅限在f1函数内部的这个for循环中。 printf("%d ", t); } for (1) { printf("%d ", t); // 错误 // t 变量的定义域/生命周期仅限在f1函数内部的这个for循环中。 break; } printf("%d ", t); // 错误 return A; } int main() { int A = 1; // 错误,已有全局变量A int j = 1; // 可以,main函数的定义域找不到j变量。 printf("%d ", j); // 错误 return A; } 函数返回值类型 函数名(传入函数的变量) {//具体的代码}int main() { return 0; }函数的声明、实现和调用C语言中,函数的“声明”和“实现”可以分开。函数的调用中,必须在“被调用函数”声明后才可以调用该函数。例如在 A 函数中调用 B 函数,则需在 A 函数之前声明 B 函数。声明函数“签名”。返回值类型 函数名(定义传入函数的变量);实现返回值类型 函数名(定义传入函数的变量) { ... 具体的代码实现 ... }以下两个例子等价。int add(int a, int b) { // a, b 形参 int c = 10; //实参 return a+b; } int main() { return add(10, 11); } int add(int a, int b); int main() { c = 10; //实参 return add(1, 1); } int add(int a, int b) { return a+b; } void A() { return; } int B() { A(); return 0; }下面的用法是错误的:int main() { return add(1, 1); } int add(int a, int b) { return a+b; } 形参与实参返回值类型 函数名(定义传入函数的变量,即形参) { ... 具体的代码实现 ... }例如在函数中:int add(int a, int b) { // a 变量和 b 变量就是:形参,没有具体的值,具体的值由调用者决定 return a+b; } int main() { int result = add(1, 1); // 调用 add 函数,传入 a=1,b=1 printf("%d\n", result); return 0; }int add(int a, int b) { // a 变量和 b 变量就是:形参,没有具体的值,具体的值由调用者决定 return a+b; } int ab(int a, int b) { return a/b; } int main() { int a = 10; int b = 8; int c = add(a, b); // 等价于:c=a+b int d = ab(a, add(b, c)) + add(a, b); // 函数的嵌套调用 // 等价于:d=(a/(b+c))+(a+b) printf("%d\n", d); // d=18 return 0; }运算符数学运算符+ 加- 减* 乘法/ 除法日常生活中的数学运算中,各个符号的运算优先级同样适用于 C 语言编程。如,乘除运算优先级高于加减,我们可以使用小括号()来优先运算我们希望优先运算的运算。例如:int A = 1 + 2 * 3; // 结果为 7 int B = (1 + 2) * 3; // 结果为 9赋值运算符赋值运算符用“等于”号:=。i += a; 实际上是: i = i + a;i -= a; 实际上是: i = i - a;同理还有*=、/=等。指针运算符* 取值运算符,解引用运算符& 取地址运算符,获得指针地址比较运算符相等 ==(人 == 帅) 帅的话返回 TRUE 不帅则返回 FALSE不等 !=(人 != 可爱) TRUE FALSE或 || OR 满足一个即可与/且 && AND 同时满足(人 == 帅) && (人 == 可爱):如果人即帅又可爱,则返回TRUE,反之返回FALSE如果说只需要帅或者可爱满足一个条件即可,那么就用||(人 == 帅) || (人 == 可爱)! 取反值如果一个条件为真,你用“!”,则得到的值为假。如果说我们在只有一个人是不丑的情况下才执行操作:(人 != 丑)(人 == 帅)!(人 == 丑)// 除法 int printf_ab(int a, int b) { // b 是被除数,不能为0. if (b == 0) return 0; // 被除数不能为0,传入代码有无,函数返回错误值0 printf("%f\n", a/b); return 1; } int main() { int r = printf_ab(1, 0); // r=0 if (!r) printf("Error\n"); return 0; } 三元运算符<条件> ? (条件满足时执行) : (不满足时执行)例如:int a = 0; int b = (a == 0) ? 1 : 2; int c = (a != 0) ? 1 : 2; // 此时 b = 1, c = 2 int b = (a == 0) ? 1 : 2; if (a == 0) b = 1; else b = 2; return (a == 0) ? 0 : 1; // 返回0条件判断中的易错点“非 0 则真”:不论是正数还是负数,只要不是0,在条件中就代表为“真”,0代表“假”。int main() { int _TRUE = 1; int _FALSE = 0; if (_TRUE) { printf("TRUE\n"); } if (!_TRUE) { printf("TRUE?\n"); } if (!_FALSE) { printf("FALSE\n"); } if (_FALSE) { printf("FALSE?\n"); } return 0; }预编译指令与头文件预编译指令所有的预编译指令,均在源码中用井号(“#”)来开始。如 #include、#defineinclude 指令引入头文件,即将头文件的内容包含到源码文件中。已知,有两个文件:A.h和A.cA.h的内容为:int A = 0;A.c的内容为:#include <stdio.h> #include <A.h> int main() { printf("%d", A); return 0; }此时,如果在A.c中,不使用#include <A.h>,而且要实现相同的功能。我们可以这么写:#include <stdio.h> int A = 0; int main() { printf("%d", A); return 0; }define 指令define 指令通常用于“宏定义”。编译器,会在编译代码前,将所有宏定义,直接替换成定义的内容。#define HELLO "HELLO" #define HI hi // char *HELLO = "\"HELLO\""; int main() { printf("%s", HELLO); //相当于 printf("%s", "HELLO"); printf("%s", HI); //错误,相当于 printf("%s", hi); return 0; }上述代码中main()函数,实际等于:int main() { printf("%s", "HELLO"); return 0; }逻辑的力量(流程控制)一个程序必须要有相应的逻辑和流程控制,我们才能让程序实现我们想要的功能。判断 if (if...else if...else if...else)if (a == b) { // a等于b,执行 } // 不论a是否等于b,都继续往下执行 if (a == c) { // a等于c,执行 } else { // a不等于c,执行 }if (a == b) { // a等于b执行 } else if (a == c) { // 如果a不等于b,a等于c执行 } else { // 都不满足,执行这里 } 循环C 语言中有多种方式实现循环。跳出循环需要用 break 关键字,终止循环,继续执行循环外面的代码。继续下一个项需要用 continue 关键字。for (条件)对于 for (;...;) 这样的 for 循环,只要条件为真(非0或“TRUE”),便会一直循环执行内部的代码,除非条件不再为真(非0或“TRUE”)或者内部有代码跳出循环。for (;a == b;) { // ... if (a == c) break; if (a == d) // ... // ... } // ...for (初始化代码; 条件; 操作)对于 for (初始化代码; 条件; 操作) 这样的 for 循环,首先会执行一遍(且只会执行一遍初始化代码。随后:判断条件是否为真,若不为真,则终止循环,否则继续;循环执行内部的代码;执行操作;除非条件不再为真(非0或“TRUE”)或者内部有代码跳出循环。for (int i = 0; i < 10; i++) { // ... if (i == 5) break; // ... // ... } int i = -1; for (i = 0; i < 10; i++) { // ... if (i == 5) break; // ... // ... }while 或 do...whilewhile () { // ... if (i == 5) break; // ... }int uninitialized = 1; do { // 至少执行一遍,是否执行第二遍,看条件。 uninitialized = init(); // 如果初始化正常,init返回0,否则返回非0的数。 } while (uninitialized) // ...选择 switch (switch...case...default)switch (被判断的值) { case <条件1>: // 满足条件1的操作 case <条件2>: // 满足条件2的操作 // case ...: default: // 所有 case 的条件,都不满足,默认执行 }switch (被判断的值) { case <条件1>: // 满足条件1的操作 break; case <条件2>: // 满足条件2的操作 case <条件3>: // 满足条件3的操作 break; case <条件4>: case <条件5>: // 满足条件4或5的操作 break; // case ...: default: // 所有 case 的条件,都不满足,默认执行 break; }注释随着我们程序复杂度的增加,代码越写越多,人脑是有极限的,我们不可能会记住我们所有写的代码的功能、目的等。所以我们引入注释,来向人类解释或说明。编译器绝对不会理会任何注释。在编译时,编译器默认忽略全部的注释。在编译器看来“不存在”“注释”。单行注释// 我们要写的字// 第一行 // 第二行 // 第三行多行注释(块注释)/* 多行这么写 1234321 sadasd */ /* 一行这么写 */常见的 C 标准库与标准函数stdio.hmath.hstring.h
2025年08月04日
4 阅读
0 评论
0 点赞