目录
3.控制符:%0.2d、%d、%f、%lf、%c、%x、%o、%s
1.什么是流程控制;程序代码执行的顺序为”自上而下,自左而右”
2.分类:for、while、do……while、break和continue等等
(A)while循环,表达式是用bool形式,真则执行假则不执行
d)如果一个函数要处理一个一维数组,则需要接收该数组的那些信息
(一)C常识
(A)算机的基本组成部分(书:计算机组成原理)
1.组成部分
CPU:负责指令与进行计算,是计算机的核心。(寄存器:CPU内部可以存储内存的一些硬件东西)
内存条:计算机的临时存储器,用于存储正在执行的程序与数据。
硬盘;是计算机的永久存储器,用于存储操作系统、应用程序与用户数据等。
显卡;用于图形的处理设备,负责将数字信号转换成可视的图像信号。
显示器;用于显示图像与文字,当计算机运行程序时,CPU从内存中读取数据与指令,通过显卡将图像信号传输到显示器上显示出来
即;硬盘中的数据调用到内存条中,CPU再处理内存条中的数据,处理完后发送给显示器,它们之间的如何运作是通过主板来运行的
2.CPU处理内存条(通过三条线:控制线、地址线、数据线):
控制线:控制数据传输的方向
数据线:用来地址传输
地址线:确定对内存条那个单元进行控制
(B)程序是如何运行的
通过编译与链接会产生一个可执行的.exc文件,所编译的软件会请求操作系统去执行.exc可执行文件,操作系统调用CPU去执行.exc文件(操作系统去控制硬件)然后在显示器上显示出来(所有的操作是靠CPU运行起来的)
(C)什么是进制的转换
1.定义:
逢几进一(二进制:逢二进一、十进制:逢十进一)
2.语言规定
八进制前要加0(零)、十六进制前要加0X或0x、十进制前什么都不加
3.在汇编语言中:
在数字后加字母B表示二进制,加字母O表示八进制,加D表示十进制,加H表示十六进制。
4.常用进制对照表
5.十进制转换成r进制的方法
除r取余,直至商0,余数倒数排列即为所要转换的进制。
(D)枚举
1.定义
枚举不需要类型,因为本质上枚举就是整形
2.用法及注意事项
(1)每一个枚举成员都以逗号隔开,最后一个成员后面不需要加逗号。
(2) 枚举名不能重复。
(3) 枚举是从第一个成员开始进行编号的,从零开始,后面递增。
(4) 可以给枚举成员赋值,赋值之后的枚举成员从赋值数依次开始递增。
(5) 给枚举变量赋值枚举成员之外的数值(也可以把枚举成员赋值)在C语言中是允许的。
(E)字节的转换
1个字节=8位(bits、byte) 1K=1024个字节 1M=1024K 1G=1024M
1K=2^10B 1M=2^10KB=2^20B 1G=2^10M=2^30B
(F)数据类型
Int、 double、float……
关于float:
变量不可以直接定义为float(float不可以直接定义),float不能保证精确的存储一个小数
float存储数据时存储不到确定值
(G)编码
编码(ASCII码、GB 2312、UTF-8(中文编码,一个中文占两个字节)):不是一个值,而是一种规定,ASCII码规定了不同的字符是使用哪个整数值去表示的。
‘A’——65 ‘a’——97 ‘0’——48
不同的码规定了不同的字母拿什么去规定。
(H)定义字符串时的常识
C语言中没有直接定义字符串的数据类型,定义字符串要用字符串数组(C语言中常用字符数组来模拟字符串的行为)
(I)控制符
1.输出控制符:printf
printf(“字符串”);
printf(“输出控制符1 输出控制符2……”,输出参数1,输出参数2);
注意:输出控制符与输出参数必须一一对应
2.输入控制符:scanf
scanf(”非输入控制符 输入控制符”,&输入参数);
&输入参数:取输入参数地址中的变量
注意:非输入控制符必须原样输入
3.控制符:%0.2d、%d、%f、%lf、%c、%x、%o、%s
演示:%x(若x为47) %x——>2f %#x——>0x2f
%X——>2F %#X——>0X2F
(J)运算符
1.算术运算符:+、-、*、/、%
2.关系运算符:>、>=、==、<、<=、!=
3.逻辑运算符:!(非)、&&(并且)、||(或)
&&:只要有一个为假语句则为假
||;要有一个为真则为真
&&左边的表达式为假,右边的表达式不执行。
||左边的表达式为真,右边的表达式不执行。
列: int i=10,k=20;
(i>2)||(k=5) 表达式(i>2)为真不执行表达式(k=5)所以结果为:i=10,k=20
(K)流程控制
1.什么是流程控制;程序代码执行的顺序为”自上而下,自左而右”
2.分类:顺序结构、选择结构、循环结构
注意if、else、for、等等循环语句默认只控制一条语句,要控制多条的话用”{}”把语句括 起来
(L)循环
1.定义:某代码会被循环执行
2.分类:for、while、do……while、break和continue等等
for语句的执行顺序: for(语句1;语句2;语句3)
语句4
执行顺序:语句1——>语句2,如果语句2成立则——>语句4——>语句3——>语句2 ;其中语句1只执行一次,语句2成立了执行语句4不成立则出循环
(N)如何看懂一个程序
1.看其流程,
2.看每个语句的功能,
3.试数(把自己想成电脑去执行,每一步都不可以少,拿小一点的数去试试)
(二)流程控制
(A)while循环,表达式是用bool形式,真则执行假则不执行
1.格式:
while (表达式)
语句;
2.while和for可以相互转换
相比下来:For逻辑更加清晰,不容异出错
3.do……while语句
格式:
do{
语句
}while(表达式);
do ……(循环体)……while(do里面的语句一定执行一次),while语句成立后执行的循环体是do后的语句:主要用于人机交互
do……while 并不等价于for,当然也不等价于while
(B)switch语句
1.格式:
2.诠释:
(1)所有case后面的常量表达式为便于描述我们称为标签,这些标签都只能是a.枚举常量(有些书称为枚举元素) b.数值常量 c.字符常量 d.常变量 e.宏名中的一种,注意普通变量,枚举变量是不能作为标签使用的
(2)switch后面括号里的“表达式”允许是任何类型,但是Vc++中只允许为int或char类型
(3)执行完一个case语句后不,流程控制就转移到下一个case语句继续执行。“case”常量表达式只是起语句标号的作用,并不是在该处进行条件判断。在执行switch语句时,根据switch()中表达式的值找到与之匹配的case语句,就从此case语句开始执行下去不再进行判断。
(C)break与continue
1.break
作用:
break如果用于循环是用来中止循环
break如果用于switch则是用于中止switch
break不能直接用于if,除非if属于循环内部的一个子句
多层for循环或者多层switch循环break用于中止最近的for语句或者switch语句
switch中的break用于中止switch(跳出switch);break还用于中止循环
2.continue
(1)作用:
用于跳过本次循环余下的语句,转去判断是否需要执行下次循环。
(2)语法规则:
(三)四大重点(数组、函数、指针、动态内存、结构体)
(A)数组
1.为什么需要数组:
为了解决大量同类型数据的存储和使用问题、为了模拟现实世界中问题
同类型数据的命名问题之类(变量具有局限性后就出现了数组)
2.定义:
把1、2、3、4、5分别赋值给a[0]、a[1]、a[2]、a[3]、a[4]
数组中的元素就是变量(数组中的变量叫元素)
3.数组的分类(一、二、多维数组)
(1)一维数组:
1)定义:
为n个变量连续分配存储空间
所有变量的数据类型必须相同
所有变量所占的字节大小必须相等
2)一维数组的操作:
a.初始化:
定义后再使用数组则代表下标,错误一行代表第六个元素
其中a、b代表第一个元素的地址
b.赋值:
(2)二维数组
1)诠释:
2)初始化:
3)二维数组内容的输出
输出规则:行先变列后变
(3)多维数组
n维数组可以当作每个元素是n-1维数组的一维数组(因为内存是线性的,二维数组与多维数组都是人们想出来更好帮助我们理解的)
(B)函数
1.为什么需要函数
避免重复行操作(更好的处理大型数据)
有利于模块化(面向过程的思想:把大问题分解成小问题)
2.什么叫做函数
逻辑上:能够完成特定功能的独立代码块
物理上:能够接受数据(当然也可以不接受数据)
能够对接受的数据进行处理
能够将数据处理的结果返回(当然也可以不返回任何值)
总结:函数是个工具,它是为了解决大量类似问题而设计的,可以把函数当成一个黑匣子。“黑匣子”:函数内部怎么处理可以视为“保护代码”
示例:
3.如何定义函数
函数的返回值 函数的名字(函数的形参列表){
函数的执行体
}
(1)函数定义的本质:
详细描述函数之所以能够实现某个特定功能的具体方法
(2)return表达式的含义:
1)中止被调用函数,向主函数返回表达式的值
2)如果表达式为空,则只中止函数,不向主函数返回任何值
3)break是用来中止循环和switch的,return是用来中止函数的(break中止循环,return中止函数)
列:
(3)返回值类型
函数返回值的类型也称函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为标准
列:
4.使用函数的具体形式
等价于
诠释:max是函数的名字、i和j是形式参数(简称形参)、void表示函数没有返回值、“1、2、3、9、-5、100”是实参
5.函数的分类
(1)有参函数和无参函数
(2)有返回值函数和无返回值函数
(3)库函数和用户自定义函数
(4)值传递函数和地址传递函数
(5)普通函数和主函数(main)
注:
(1)一个函数必须有且只能有一个主函数
(2)主函数可以调用其他函数,其他函数不可以调用主函数
(3)普通函数可以相互调用
(4)主函数是程序的入口也是程序的出口
6.函数使用时注意问题
(1)函数调用和函数定义的顺序
如果函数调用写在了函数定义的前面,则必须加函数前置声明
函数前置声明:
1)告诉编译器即将可能出现的若干个字母代表的是一个函数
2)告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况
3)函数声名是一个语句,末尾必须加分号
4)对库函数的声明是通过#include<库函数名>来引用的
写代码时的建议:
有且只有一个主函数(程序是从主函数进入的);程序自上而下编译所以把主函数写在最上面最好,或者可以声明函数(声明函数时声明函数的形参类型就好了可以不用具体声明函数的形参名(看指针交互两数类型))
(2)形参和实参的光系
个数相同、位置一一对应、数据类型必须相互兼容
(3)如何在软件开发中合理的设计函数来解决实际问题
1)一个函数的功能尽量独立、单一
2)多学、习多模仿大牛代码
3)把函数的利用率提高(设计函数时候功能单一的话更有利于其利用)
实列比较:
题1:求1到某个数字之间的素数(包括此数)自用主函数实现:
局限性:
1)代码的重复性不高
2)代码不容易理解
题2:求1到某个数字之间的素数(包括此数),并将其输出用一个函数来判断一个数字是否是素数
优点:
1)代码比题1更易理解
2)代码的可重用性比题1更高
缺点:
可重用性任然不是很高(比如求1000个数字,求它们每个数字从1到它本身的素数)
(G)常用系统函
C语言书本后面有。列sqrt、abs
(H)数据结构中的递归
要知道栈(压栈(把元素放进栈里)和出栈)
(I)变量的作用域与存储方式
(1)按作用域分:
1)全局变量
诠释:在所有函数外部定义的变量叫做全局变量
其使用范围:从定义位置开始到整个程序结束
例子:
2)局部变量
诠释:在一个函数内部定义的变量或者函数的形参
适用范围:只能在本函数内部使用
注意:在一个函数内部,全局变量与局部变量命名冲突的问题时(在一个函数内部如果定义的局部变量名和全局变量名一样时),局部变量会屏蔽全局变量
(C)指针
(1)指针的基础概念
指针(地址)定义:内存单元的编号,从零开始的非负整数
使用范围:4G[0到4G减1](32位是4G,64位是4乘以4G)
本质:是一个受限制的非负整数(可以相减:可以算出两地址相隔多少个地址)
总结:指针就是地址(内存单元的编号),也可以说是内存单元的编号;指针变量即地址变量(指针变量:可以存放其它变量的地址)
定义一个指针:
指针的引用(*p的定义):
(2)指针与指针变量的区别
1)指针就是地址,地址就是指针
2)指针就是内存单元的编号
3)指针变量是存放地址的变量
4)指针和指针变量是两个不同的概念
5)通常我们叙述时我们会把指针变量简称为指针,实际上它们含义并不一样
(3)指针的重要性
1)可以表示一些复杂的数据结构(数据结构中链表也可以)
2)快速的传递数据
3)使函数返回一个以上的值
4)能直接访问硬件(因为其存放内存地址)
5)能偶方便的处理字符串
6)是理解面向对象语言中引用的基础
总结:指针是C语言的灵魂!!!
(4)指针的分类
1)基本类型指针
2)常见错误:
3)指针交换两数:
4)引伸:
a.*号的三个含义:
(a)乘法:
(b)定义指针变量:
int *p//定义了一个名叫p的变量,int *表示p只能存放int变量的地址
(c)指针运算符:
a)改运算符放在已经定义好的指针变量的前面
b)如果p是一个已经定义好的指针变量则*p表示以p的内存为地址的变量
b.如何通过被调函数修改主函数普通变量的值
(a)实参必须为改普通变量的地址
(b)形参必须为指针变量
(c)在被调函数中通过“*形参名=……”的方式就可以修改主调函数相关变量的值
5)指针延展
1.指针和数组
a.指针和一维数组:
a)一维数组
一维数组名是个指针常量,它存放的是一维数组第一个元素的地址
b)下标和指针的关系
如果p是个指针变量,则p[i]永远等价与*(p+i)
c)界定一个一维数组需要几个参数
需要连个参数:数组第一个元素的地址、数组的长度
d)如果一个函数要处理一个一维数组,则需要接收该数组的那些信息
需要四个信息:数组的内存地址(或引用)、数组长度、数组类型、数组元素
e)指针变量的运算
指针变量不能相加、不能相减、不能相除
如果两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才可以相减
例子:
f)一个指针变量占几个字节
假设p指向char类型变量(char型是1个字节)
假设q指向int类型变量(int型变量是4个字节)
假设r指向double类型变量(double变量是八个字节)
即使指针指向的变量的类型占的字节数不同但p、q、r本身所占的字节数是一样的
总结: 一个指针变量,无论它指向的变量占几个字节,该指针变量所占字节与计算机地址线有个:32位计算机占4字节,64位计算机占8字节
一个变量的地址使用该变量首字节的地址来表示
不同计算机的占字节位数不同原因:
32根地址线(32位计算机)以0、1(高低电平)构成了存储单元,所以每一个存储单元就是32个bit,拿出一个单元存储首地址,而32bit=4byte(一个字节8位,四个字节32位)同理64根地址线(64位计算机)占八个字节
b.指针和二维数组:
2.指针和函数
3.指针和结构体
4.多级指针
指针的指针(二级指针):用于实现跨函数使用内存,指针的指针的指针
(D)动态内存分配:
1.传统数组的缺点:
传统数组也叫静态数组
(1)数组长度必须事先制定,且只能是长整数,不能是变量
列:int a[5];//OK int len=5;int a[len];//error
(2)传统形式定义的数组,该数组的内存程序员无法手动释放;在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放 (3)数组的长度一旦定义,其长度就不能再更改;数组的长度不能在函数运行的过程中动态的扩充或缩小
(4)A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行完毕之后,A函数中的数组将无法再被其他函数调用,传统方式定义的数组不能跨函数使用(函数一中止,其它函数就无法使用了)
2.为什么需要动态内存分配:
解决了传统数组以上四个缺陷
3.动态数组的构造(动态内存分配实例):
使用函数:malloc函数(动态内存分配函数)——memory(记忆,内存)allocate(分配):
用法及辅助理解
制作一个简单的动态数组
辅助理解:
4.跨函数使用内存问题
主要涉及到静态分配和动态分配的内存问题
(1)静态分配内存:
如局部变量,在函数执行完成后,其占用的内存会被自动释放,因此无法跨函数使用
(3)动态分配内存:
1)通过malloc、calloc、new等函数分配内存,可以在不同函数之间享用和使用,且可通过free或delete手动释放
2)使用指针可以在不同函数之间传递动态分配的内存地址,从而实现跨函数使用内存
5.静态内存和动态内存的比较
(1)分配方式:
静态内存:在编译阶段由编译器自动分配
动态内存:需要程序员手动分配和释放
(2)分配的时间:
静态内存:发生在程序编译和连接的时候
动态内存:发生在程序调入和执行的时候
(3)资源占用:
静态内存:其分配不占用CPU资源,因为它们在编译时就已确定
动态内存:其分配和释放会占用CPU资源,因为它们在运行时进行的
(4)所在位置
静态内存:通常在栈上分配
动态内存:在堆上分配
(5)优缺点:
1)静态内存:
a.优点:创建时间确定、不会出现分配失败的情况(因为大小在编译时已知)
b.缺点:每位价格高,因为集成度较低
2)动态内存:
a.优点:每位价格低、集成度高
b.缺点:功耗较小、需要动态刷新电路进行维护,且在运行时可能因无法确定内存需求而导致分配失败,对程序员代码写作能力需求高
(6)使用场景:
静态内存:适用于Cache(高速缓冲存储器)或存储速度要求高的小容量为主存
Cache的主要作用是解决CPU与内存之间速度不匹配的问题
动态内存:适用于大容量为主存
(E)结构体
1.为什么需要结构体:
为了表示一些复杂的事物类型,而普通的基本类型无法满足实际需求
2.什么叫做结构体
把一些基本类型类型组合在一起形成的一个新的复合数据类型,这个叫做结构体
3.结构体表达的三种方式
加深理解:
结构体在数组上的使用
4.怎么去使用结构体变量
(1)怎么定义和赋值结构体
1)在定义的同时去赋值
2)定义后再挨个赋值
(2)如何取出结构体中的变量:
1)结构体变量名.成员名(直接引用)
2)结构体变量名->成员名(指针指向)
在此中:
a. pst->age 在计算机中内部会转化成(*pst).age
b.因此pst->age ==(*pst).age==st.age
c. pst->age的含义是pst所指向那个结构体变量中的age这个成员
辅助理解:
指针变量名->成员名在计算机内部会被转化成(*指针变量名).成员名的方式来执行所以说这两种方式是等价的
3)结构体变量的运算
结构体变量不能相加、不能相减、不能相互乘除当可以相互赋值
4)结构体变量和结构体指针变量作为函数参数传递的问题(函数输出时传递)
推荐使用结构体指针变量作为函数参数来传递(指针的优点)