C语言
- 前言
- 第一章 初识C语言
- 1.1 C语言的起源
- 1.2 选择C语言的理由
- 1.3 使用C语言的7个步骤
- 第二章 数据和C
- 2.1 变量和常量
- 2.1.1变量定义
- 2.1.2 常量的定义
- 2.2 数据类型关键字
- 第三章 运算符、表达式和语句
- 3.1 基本运算符
- 3.1.1 算术运算符
- 3.1.2 关系运算符
- 3.1.3 逻辑运算符
- 3.1.3 赋值运算符
- 3.1.4 优先级
- 3.2 表达式
- 3.3 语句
- 第四章 循环
- 4.1 while循环
- 4.2 for循环
- 4.2 do .. while循环
- 4.3 循环控制语句循环
- 4.4 如何选择循环
- 第五章 判断控制
- 5.1 if 语句
- 5.2 if..else 语句
- 5.3 嵌套 if 语句
- 5.4 switch 语句
- 5.5 三元运算符
- 第六章 数组和指针
- 6.1 数组
- 6.1.1 声明数组
- 6.1.2 初始化数组
- 6.1.3 访问数组元素
- 6.2 多维数组
- 6.2.1 二维数组
- 6.3 指针
- 6.3.1 指针变量的赋值
- 6.3.2 指针的引用
- 6.4 指针和数组
- 6.4.1 指针和一维数组
- 6.4.2 指针移动法
- 6.4 二维数组
- 第七章 函数
- 7.1 函数概述
- 7.1.1 函数的分类
- 7.1.2 函数的定义和返回值
- 7.1.3 函数的调用和返回值
- 7.1.4 函数中参数的传递形式
- 7.2 主函数main()
- 7.2.1 无参数形式
- 7.2.2 有参数形式
前言
因为准备要出去实习了,所有想要回顾一下整个大学生涯学习了哪些技术,整理出来让自己形成知识体系架构。
ps:本栏目纯属个人学习所得,有错的话,还请大佬指正出来,谢谢😊😊
第一章 初识C语言
欢迎来到C语言的世界。C是一门功能强大的专业化编程语言,深受业余编程爱好者和专业程序员的喜爱。我们先来了解C语言的起源和一些特性,包括它的优缺点。然后,介绍编程的起源并探讨一些编程的基本原则。最后,讨论如何在一些常见系统中运行C程序。
1.1 C语言的起源
1972年,贝尔实验室的丹尼斯.里奇(Dennis Ritch) 和肯●汤普逊(Ken Thompson) 在开发UNIX操作系统时设计了C语言。然而,C语言不完全是里奇突发奇想而来,他是在B语言(汤普逊发明)的基础上进行设计。至于B语言的起源,那是另一个故事。C语言设计的初衷是将其作为程序员使用的-种编程工具,因此,其主要目标是成为有用的语言。
1.2 选择C语言的理由
在过去四五十年里,C语言已成为最重要、最流行的编程语言之一。它的成长归功于使用过的人都对它很满意。过去20多年里,虽然许多人都从C语言转而使用其他编程语言(如,C++、ObjectiveC、Java等),但是C语言仍凭借自身实力在众多语言中脱颖而出。在学习C语言的过程中,会发现它的许多优点下面,我们来看看其中较为突出的几点。
- 设计特性–编写的程序更易懂、更可靠
- 高效性–相对紧凑,运行速度快
- 可移植性–在其他系统都可以运行
- 强大而灵活–许多编译器和解释器都是用C语言编写的
- 面向程序员–能让程序员简洁地表达自己的意图
1.3 使用C语言的7个步骤
- 定义程序的目标
- 设计程序
- 编写代码
- 编译
- 运行程序
- 测试和调试程序
- 维护和修改代码
想要具体了解的可以看我的这篇文章 使用C语言的步骤
第二章 数据和C
2.1 变量和常量
有些数据类型在程序使用之前已经预先设定好了,在整个程序的运行过程中没有变化,这些称为常量(constant)。其他数据类型在程序运行期间可能会改变或被赋值,这些称为变量(variable)。在后面的学习中我们会经常用到。
2.1.1变量定义
type variable_list;
int i, j, k;
char c, ch;
float f, salary;
double d;
extern int a = 5, b = 5; // a 和 b 的声明与初始化
int c = 3, d = 5; // 定义并初始化 c 和 d
byte e = 22; // 定义并初始化 e
char x = 'x'; // 变量 x 的值为 'x'
2.1.2 常量的定义
整数常量可以是十进制、八进制或十六进制的常量
1234 /* 合法的 */
520u /* 合法的 */
0xFeeL /* 合法的 */
2.2 数据类型关键字
关键字 | 解释 |
---|---|
char | 声明字符型变量或函数 |
double | 声明双精度变量或函数 |
enum | 声明枚举类型 |
float | 声明浮点型变量或函数 |
int | 声明整型变量或函数 |
long | 声明长整型变量或函数 |
short | 声明短整型变量或函数 |
signed | 声明有符号类型变量或函数 |
struct | 声明结构体变量或函数 |
union | 声明共用体(联合)数据类型 |
unsigned | 声明无符号类型变量或函数 |
void | 声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) |
第三章 运算符、表达式和语句
3.1 基本运算符
逐一介绍算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和其他运算符.
3.1.1 算术运算符
运算符 | 解释 |
---|---|
+ | 把两个操作数相加 |
- | 从第一个操作数中减去第二个操作数 |
* | 把两个操作数相乘 |
/ | 把两个操作数相除 |
% | 整除后的余数 |
++ | 自增运算符,整数值增加 1 |
- - | 自减运算符,整数值减少 1 |
3.1.2 关系运算符
运算符 | 解释 |
---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真 |
3.1.3 逻辑运算符
运算符 | 解释 |
---|---|
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 |
3.1.3 赋值运算符
运算符 | 解释 |
---|---|
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 |
<<= | 左移且赋值运算符 |
>>= | 右移且赋值运算符 |
&= | 按位与且赋值运算符 |
^= | 按位异或且赋值运算符 |
|= | 按位或且赋值运算符 |
3.1.4 优先级
运算符优先级为表达式中求值顺序提供重要依据。优先级决定了求值顺序。
乘除>加减>移位>关系>相等>位>逻辑>条件>赋值
3.2 表达式
表达式(expression) 由运算符和运算对象组成
下面是一些表达式:
4
-6
4 + 21
a * (b + c / d)/20
q = 5 * 3
x > 3
3.3 语句
语句是C程序的基本构建块,一条语句相当于一条完整的计算机指令,在C中语句是以分号结尾。
le = 4; //这是一条语句
; //空语句是最简单的语句
8; //不做任何运算,不算真正的语句
2 + 5; //不算真正的语句
x = 520;
++x;
y = sqrt(x); //一条完整的指令
复合语句:用大括号括起来的一条或多条语句,复合语句也称块
while(true){
sum = 10 + x
}
第四章 循环
循环语句允许我们多次执行一个语句或语句组。
4.1 while循环
只要给定的条件为真,C 语言中的 while 循环语句会重复执行一个目标语句。
while(表达式)
{
x += 520; //这是循环体
}
当表达式为true时执行循环,反之则退出循环
4.2 for循环
for 循环允许您编写一个执行指定次数的循环控制结构。
for(init; condition; increment)
{
statement(s);
}
1.init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
2.接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
3.在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
4.条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。
示例:
#include <stdio.h>
int main ()
{
/* for 循环执行 */
for( int a = 10; a < 20; a = a + 1 )
{
printf("a 的值: %d\n", a);
}
return 0;
}
输出10-19.
4.2 do … while循环
与 for 和 while 循环区别,它们是在循环头部测试循环条件。在 C 语言中,do…while 循环是在循环的尾部检查它的条件。do…while 循环与 while 循环类似,但是 do…while 循环会确保至少执行一次循环。
do
{
statement(s);
}while( condition );
循环中的 statement(s) 会在条件被测试之前至少执行一次。
4.3 循环控制语句循环
控制语句改变你代码的执行顺序。
控制语句 | 解释 |
---|---|
break | 终止循环或 switch 语句,程序流将继续执行紧接着循环或 switch 的下一条语句 |
continue | 告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代 |
goto | 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句 |
注意:如果调试的时候进入无限循环,您可以按 Ctrl + C 键终止一个无限循环。
4.4 如何选择循环
如何选择使用哪一种循环?首先,确定是需要入口条件循环还是出口条件循环。通常,入口条件循环用得比较多,有几个原因。其一,一般原则是在执行循环之前测试条件比较好。其二,测试放在循环的开头,程序的可读性更高。另外,在许多应用中,要求在一开始不满足测试条件时就直接跳过整个循环。那么,假设需要一个入口条件循环,用for循环还是while循环?这取决于个人喜好,因为二者皆可。要让for循环看起来像while循环,可以省略第1个和第3个表达式。例如:
for( ; test; )
//效果相同
while(true)
要让while循环看起来像for循环,可以在whi le循环的前面初始化变量,并在while循环体中包含更新语句。例如:
初始化;
while(测试)
{
其他语句;
更新语句;
}
//效果相同
for(初始化;测试;更新)
其他语句;
一般而言,当循环涉及初始化和更新变量时,用for循环比较合适,而在其他情况下用while循环更好。像下面这种情况就用while循环就很合适
while(scanf("%ld",&num) == 1)
对于涉及索引计数的用for循环合适
for(count = 1 ;cunt <=100; count++)
第五章 判断控制
本章介绍分支结构,让程序根据测试条件执行相应的行为。
5.1 if 语句
一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。
if(条件)
{
语句;
}
如果布尔表达式为 true,则 if 语句内的代码块将被执行。如果布尔表达式为 false,则 if 语句结束后的第一组代码(闭括号后)将被执行。
5.2 if…else 语句
一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为 false 时执行。
if(条件)
{
如果条件为真执行的语句;
}
else
{
如果条件为假执行的语句;
}
如果布尔表达式为 true,则执行 if 块内的代码。如果布尔表达式为 false,则执行 else 块内的代码。
5.3 嵌套 if 语句
在 C 语言中,嵌套 if-else 语句是合法的,这意味着您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。
if(条件1)
{
当条件1为真时执行的语句;
if(条件2)
{
当条件2为真时执行的语句;
}
}
5.4 switch 语句
一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。
switch(expression){
case constant-expression :
statement(s);
break; /* 可选的 */
case constant-expression :
statement(s);
break; /* 可选的 */
/* 您可以有任意数量的 case 语句 */
default : /* 可选的 */
statement(s);
}
5.5 三元运算符
可以用来替代 if…else 语句
表达式 ? 执行1 : 执行2;
如果表达式为真,执行1,为假时执行2.
第六章 数组和指针
本章简单介绍数组,数组能高效便捷地处理数据。
6.1 数组
数组由数据类型相同的一系列元素组成,想要用到数组时,通过声明数组告诉编译器数组中含有多少元素和这些元素的类型,
6.1.1 声明数组
//一些数组声明
int main(void)
{
float day[520]; //内含520个float类型元素的数组
char code[12]; //内含12个char类型元素的数组
int aet[10]; //内含10个int类型元素的数组
}
数组中的特定元素可以通过索引访问,第一个索引值为 0。
6.1.2 初始化数组
数组通常被用来存储程序需要的数据。
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
//大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
//如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数
6.1.3 访问数组元素
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边
double salary = balance[9];
6.2 多维数组
C 语言支持多维数组.
type name[size1][size2]...[sizeN];
6.2.1 二维数组
多维数组最简单的形式是二维数组。一个二维数组,在本质上,是一个一维数组的列表。声明一个 x 行 y 列的二维整型数组。
type arrayName [ x ][ y ];
初始化二维数组,多维数组可以通过在括号内为每行指定值来进行初始化。
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
6.3 指针
指针提供一种以符号形式使用地址的方法,指针能更有效地处理数组。
指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。
type *var_name;
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */+
6.3.1 指针变量的赋值
指针变量里面存放的是一个地址,所有可以借助取地址符(&)为指针赋值。在指针赋值时,,一定要保证指针的类型要与所指变量的类型一致。
int m = 10;
int *p;
p = & m;
6.3.2 指针的引用
在使用指针的时候,首先认识两个运算符
- & 取地址符
- * 针对指针变量的定义而言,称为指针变量标识;而对于指针变量的引用而言称为间接访问运算符,也称为取内容运算符
int a =10;
int *p;
p = &a;
printf("%d\n",*p);
6.4 指针和数组
指针通常会用到数组上面来。
6.4.1 指针和一维数组
int a[5] = {10,20,30,40,50};
int *p;
p = a;
++p;
p+2;
由于a是地址常量,本身不能发生改变,而指针是变量,可以进行改变,即可进行自加,自减运算。
6.4.2 指针移动法
#include<stdio.h>
main()
{
int a[5];
int *p;
for(p=a;p<=a+4;p++)
scanf("%d",p); //指针指向地址
for(p=a;p<=a+4;p++)
{
printf("%4d",*p); //指针移动,间接取内容运算
}
6.4 二维数组
对于二维数组中元素的引用,可以通过下标法,但同样也可以通过指针的形式加以引用。
- a[i][j]地址的引用
&a[i][j],a[i]+j,*(a+i)+j
- a[i][j]元素的引用
a[i][j],\*(a[i]+j),\*(*a+i)+j)
第七章 函数
每个C语言程序都是由若干个函数组成,每个程序中有且只有一个主函数main(),并且每次运行的时候都是从主函数开始执行。
7.1 函数概述
函数是用得非常多的一种结构。
7.1.1 函数的分类
- 库函数
关于库函数前面我们用到的输入输出函数:scanf()和printf(),取绝对值函数abs(),字符串中gets()、puts()、strlen()、strcmp()等。这些函数由C语言系统提供·,用户无需定义,只需在程序前包含有该函数原型的头文件,例如#include<stdio.h>,#include<math.h>,#include<string.h>等,就可以在程序中直接调用。 - 用户定义函数
用户按需求自定义的函数称为用户自定义函数,这种函数不仅要在程序中定义函数本身,而且在主调函数模块中还必须对该被调函数进行类型说明,然后才能使用。
7.1.2 函数的定义和返回值
类型关键字 函数名([参数列表])
{
函数体
}
void p_start()
{
printf("****\n");
}
7.1.3 函数的调用和返回值
#include<stdio.h>
int sum(int a,int b) //定义求和函数
{
int c;
c = a + b;
return c; //返回值
}
int sub(int a,int b) //定义求差函数
{
int c;
c =a - b;
return c; //返回值
}
main()
{
int m,n,s1,s2;
scanf(%d%d",&m,&n);
s1 = sum(m,n); //调用sum函数
s2 = sub(m,n); //调用sub函数
printf("sum:%d\n sub:%d\n",s1,s2);
}
函数体中最后条语句
return 表达式;
这里的表达式的值是整个函数的返回值,且表达式的类型要与函数的类型保持一致。
函数调用
函数名(参数列表);
7.1.4 函数中参数的传递形式
关于参数的传递有两种形式,即按值传递和按地址传递
- 按值传递
如果实际参数是变量或者常量,称为按值传递,按值传递不改变原有变量的数值,是单向的传递过程。 - 按地址传递
如果实际参数是地址,称为按地址传递,按地址传递会改变原有变量的数值。
7.2 主函数main()
通常情况下,主函数main()分为无参形式和有参形式两种
7.2.1 无参数形式
int main(void)
{
....
return 0;
}
该主函数属于整型,函数的返回值return 0 与之对应,返回给操作系统,表示程序正常退出。
7.2.2 有参数形式
int main( int argc,char *argv[])
{
....
return 0;
}
对于主函数有参数形式而言,需要向其传递参数,但是,其他任何函数都不能调用主函数,因此,只能由程序之外传递而来。