C语言
- 知识基础
- 控制语句
- 函数
- 输入输出
- 指针和数组
- 用户自定义数据类型
- 文件操作
目录
一、程序设计
什么是程序设计?程序设计与计算机的关系。。。
程序设计是给出解决特定问题程序的过程,现实生活中我们解决问题提出解决办法的过程某种意义上也是一种程序设计;
计算机作为一种计算工具,能够自动、高速的处理解决问题,但计算机不会自己“想办法”,所以解决问题的办法需要由“程序员”提出并告诉计算机遇到“这样的”问题应该“这样”解决;
二、编程语言
告诉?怎么让计算机听懂程序员提出的解决办法
计算机是以二进制运行的工作的,只处理0
和1
,想要计算机按要求工作只能对它输入01串
,单纯的0 1
没有任何意义,所以需要对其制定规则(编码),经过编码后计算机就拥有了属于自己的语言体系(指令集)。
计算机如何通过“0 1”指令运作?——《计算机组成原理》
1.机器语言
计算机能够直接识别和接受的二进制代码,这种语言显然十分的难以理解,如果程序员直接使用这种语言进行程序设计,虽然计算机能够直接使用设计出的程序,但是大大提高了程序设计的难度,设计出的程序难以理解,也不可能设计出复杂、庞大的程序。
2.汇编语言
使用一些英文字母和数字代表一个指令(一个01
串);这样在程序设计中可以提高速度,但这样的汇编程序计算机无法直接识别,所以需要汇编程序将汇编语言“翻译”成机器语言。
汇编一定程度上加快了程序设计的速度,但是不同型号的计算机上机器语言和汇编语言是互不通用的,汇编语言仍然有赖于机器特性,使用难度较高。
机器语言和汇编语言统称低级语言。
3.高级语言
为解决低级语言的缺点,设计提出了高级语言,更加接近于人们使用的自然语言和数学语言,更加容易理解,不依赖于具体的机器。同样,高级语言也不能被计算机直接识别,需要通过编译程序“翻译”成机器语言。高级语言写的程序称为源程序经过编译得到目标程序。
源程序如何得到目标程序?——《编译原理》
高级语言经历了不同的阶段:非结构化——>结构化;面向过程——>面向对象;
三、C语言简介
C语言的一些特点,为啥要从C语言学起嘞
编程语言种类多样,其中永远的经典当然是C语言,它是结构化 面向过程的语言,因为诞生的比较早,其设计中的部分还比较贴近计算机底层,对C语言的学习能很好的帮助我们理解计算机的工作。
特点:简洁、灵活;运算符丰富;数据类型丰富;结构化控制语句;设计自由度大;允许位操作,能够直接访问物理地址;可移植性好;程序执行效率高。
学习目标:
- 掌握基础基础的数据类型;
- 掌握高级编程语言基础语法;
- 掌握结构化编程控制语句的使用;
- 熟悉面向过程的编程思想;
- 熟悉模块化编程思想。
四、C语言词法
编程语言的“字”、“词”,及其组成规则
C语言的源程序能够准确无误的表达一个算法,无歧义的输出想要的结果,要实现这些复杂的功能,最基础的要有表达各种词意的单词和表达数据的方式,因此各种高级语言中都定义了标识符、关键字、运算符——表达词义;定义常量、变量并用数据类型区分各种数据——表达数据。
1.标识符
标识符是用来标识一个实体(变量名、函数名、常量名…)的符号,是程序员自定义的,用来区分含义、功能不同的部分,C语言标识符符合以下规则:
- 标识符由字母、数字、下划线组成,并且首字符不能是数字;
- 不能把C语言关键字作为标识符;
- 严格区分大小写;
定义标识符的一般原则:
- 见名知义;
- 自定义数据类型名:首字母大写,之后每个单词首字母大写;
- 变量名、函数名:首字母小写,之后每个单词首字母大写;
- 常量名:全部大写。
2.关键字
关键字是已经被系统定义了,具有特殊意义的字符串;我们定义的标识符不能与关键字相同。C语言中的关键字:
- 用于声明某种数据类型的变量或函数:
auto
、short
、int
、long
、float
、double
、char
… - 用于声明用户自己的数据类型:
struct
、union
、enum
… - 用于声明变量或函数的存储属性:
const
、unsigned
、extern
、static
… - 用于控制语句:
do
、while
、for
、if
、else
、switch
、case
、default
、goto
、continue
、break
、return
… - 其他:
sizeof
、typedef
…
3.运算符
程序的工作是对数据进行加工,使用标识符和关键字我们已经可以定义和控制一个数据,接下来就需要使用运算符对数据进行运算,才能实现程序的功能。
表达式:算数运算符和括号将运算对象(操作数)连接起来,形成一个表达式;运算结果为该表达式的值,表达式的数据类型与运算过程有关。
举例中所以操作数a,b,c都可以是表达式的值
- 算数运算符
算符 | 含义 | 举例 | 结果 |
---|---|---|---|
+ | 加号 / 正号 | a+b / +a | a与b的和 / a的值 |
- | 减号 / 负号 | a-b / -a | a与b的差 / a的负值 |
* | 乘号 | a*b | a与b的乘积 |
/ | 除号 | a/b | a除以b的商 |
% | 取余 | a%b(必须是整型) | a除以b的余数(整型数据) |
++ | 自加 | ++a / a++ | a+1的值 / a的值,a+1 |
- - | 自减 | - -a / a- - | a-1的值 / a的值,a-1 |
- 关系运算符
算符 | 含义 | 举例 | 结果 |
---|---|---|---|
< | 小于号 | a<b | 真(True)或假(False) |
> | 大于号 | a>b | True or False(在C语言中可以是整型1 or 0) |
<= | 小于等于号 | a<=b | True or False |
>= | 大于等于号 | a>=b | True or False |
== | 等于号 | a==b | True or False(区别于赋值号) |
!= | 不等于号 | a!=b | True or False |
- 逻辑运算符
算符 | 含义 | 举例 | 结果 |
---|---|---|---|
! | 非 | !a | 真(True)或假(False) |
&& | 与 | a&&b | True or False(在C语言中可以是整型1 or 0) |
|| | 或 | a||b | True or False |
- 位运算符
算符 | 含义 | 举例 | 结果 |
---|---|---|---|
& | 按位与 | a&b | 直接对0 1 串进行操作,考虑1bit的情况,一般会认为是整型 |
| | 按位或 | a|b | —— |
~ | 按位取反 | ~a | 1 ->0 ;0 ->1 |
^ | 按位异或 | a^b | 1^1 |0^0 ->0 ;1^0 |0^1 ->1 |
>> | 位右移 | a>>n(n是整型) | 低位会被丢弃,高位会依据数据类型补位 |
<< | 位左移 | a<<n(n是整型) | 低位补零,高位可能会产生溢出 |
- 赋值运算符
算符 | 含义 | 举例 | 结果 |
---|---|---|---|
= | 将右值赋值给左值 | a=b | a的值变为b的值 |
算符 = | 扩展的赋值号 | a算符 =b | a的值变为a算符 b的值 |
- 其他运算符
种类 | 算符 | 含义 | 举例 | 结果 |
---|---|---|---|---|
条件运算符 | ? : | 选择结构 | a?b:c | a应该是bool 类型a==True 取b,a==False 取c |
逗号运算符 | , | 分隔 | (a,b,c) | 辅助作用 |
指针运算符 | * | 解引用 | *a | a地址空间中的数据 |
& | 取地址 | &a | a数据空间的地址 | |
强制类型转换 | ( ) | 类型转换 | (int)a | a强制转换为int型 |
下标运算符 | [ ] | 求下标 | n[a] | n数组地址空间,下标为a的数据 |
成员运算符 | . | 取对象 | n.m | 得到n的成员m的值 |
-> | —— | p->m | 得到指针p地址空间内成员m的值 |
五、数据类型
要正确的处理数据,要对不同的数据进行分类,以此来决定可以进行的操作,这是一种规定,所有的常量或变量都必须主动或被动地被确定为一定的数据类型,这样才可以分配存储空间,并进行读写操作!
《计算机原理》课程中详细学习各种数据类型的编码、存储方式。
基本类型:int
、short
、long
、long long
、char
、bool
;float
、double
;
这些基本类型有不同取值范围,我们可以使用unsigned
关键字使整型类型声明为无符号。
类型 | 字节数 | 取值范围 |
---|---|---|
整型 | —— | —— |
int | 4 | -2147483648~2147483647 |
unsigned int | 4 | 0~(232-1) |
short | 2 | -215~(215-1) |
unsigned int | 4 | 0~(216-1) |
long | 4 | -2147483648~2147483647 |
unsigned long | 4 | 0~(232-1) |
long long | 8 | -263~(263-1) |
unsigned long long | 8 | 0~(264-1) |
char | 1 | -128~127 |
unsigned char | 1 | 0~255 |
浮点型 | —— | —— |
float | 4 | 0以及1.2*10-38~3.4*1038(绝对值,有效数字:6) |
double | 8 | 0以及2.3*10-308~1.7*10308(绝对值,有效数字:15) |
源程序中使用的数据主要有“变量”、“函数返回值”、“常量”、“表达式结果”,它们的数据类型是如何确定的呢?
1.声明确定数据类型
变量遵循先定义,后使用的原则,如何定义一个变量呢?
数据类型+变量名;
这样的声明之后,系统将按照数据类型的规定为该变量分配空间(对某些特殊的类型,这个空间需要用户主动去申请,但一般是自动分配)。
类似的,函数返回值类型在函数声明中确定:
返回值类型+函数名( ... ){...}
需要注意的是返回值类型可以为void
(空)。
2.常量的默认数据类型
常量是程序运行过程中其值不能被改变的量;在程序中直接以规定格式出现,可以被系统识别并设置成默认数据类型,常见形式如下:
- 整型常量:十进制
105
、十六进制0x5c
、八进制073
、二进制b0101
这样的数据出现,系统默认确定数据类型来处理,C语言中默认为int
类型,如果超出取值范围,则按照long long
处理。
特别的,在数据后面加上后缀L
、LL
直接声明为更大的数据类型;后缀U
表示无符号型。 - 实型常量:小数形式
3.1415926
、指数形式12.34e3
(12.34*103)
这样的数据,系统默认按照double
型处理。可以加上后缀F
,直接声明为较小的float
型;后缀U
表示无符号型。 - 字符常量:普通字符
'A'
、转义字符'\n'
这样的字符系统分配一个字节的存储空间,定位char
型。 - 字符串常量:
"张三"
这样的值系统可以自动分配一个char*
数组存储,可以用指针访问其中的单个字符。
-符号常量:#define PI 3.1415926
使用指令,指定一个符号代表一个常量,常量的类型取决于后者,例子中PI
数据类型应该是double
。
3.类型转换确定数据类型
类型转换是数据处理过程中出现的,主要包括:
- 自动类型转换:两种数据类型可以兼容并且目标变量取值范围大于源变量,自动转为范围更大,精度更高的数据类型;
(1)int
、flaot
、double
混合运算,系统自动将前两者转为double
,再进行计算。
(2)char
与整型数据运算,会以ASCII码值进行计算! - 强制类型转换:使用强制类型转换符
(数据类型)表达式
,这种操作可能会损失精度。
需要熟练掌握混合运算中的类型转换,尽量避免程序中常量数据类型判断错误产生的精度损失,例如:double d = 3/2; 预期结果是1.5,但事实上d中的值为1,因为常量3、2均为int类型,运算结果为int型,然后将int型赋值给double,自动类型转换发生,产生了精度损失!!!
六、C语句
使用标识符、关键字、表达式足以表达对数据的处理,**在结构化编程中用各种语句来实现对数据的一个动作。**不同的语句形式和作用各有不同,现在我们重点了解表达式语句中最常用的赋值语句,其他各种控制语句,函数调用语句等我们会在后续学习中了解到。
1.分类及作用
种类 | 示例 | 作用 |
---|---|---|
预处理指令 | #include <stdio.h> | 严格意义上并非语句,在编译阶段完成预处理工作 |
声明语句 | int a; | 可以声明变量、函数,结构体等,并不进行具体操作 |
控制语句 | if(…){…}else{…} | 完成选择、循环、返回、跳转等控制程序走向的功能 |
函数调用语句 | printf(“Hello World”); | 调用一个函数完成函数功能 |
表达式语句 | a++; | 对数据的一些操作 |
赋值语句 | a=i+3; | 表达式语句的一种,实现对变量的赋值等操作 |
2.赋值语句
表达式;
这样组成的语句称为表达式语句,例如:x+y;
这个语句虽然合法,但是表达式的结果并不会被存储下来,所以并没有意义,所以一般有赋值的操作变量 赋值运算符 表达式;
。
- 赋初值
- 赋值中的类型转换
- 赋值表达式和赋值语句
总结
对于所有的编程语言都会有这些基础知识,我们要能够清醒的剖析一个程序的每一个部分,由最底层的机器码,到C语言的(标识符、关键字、数据量)->(C语句)->…,接下来需要了解结构化编程的重要部分控制语句。