file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png
VC++6.0软件使用:保存ctrl加s。过五秒就按,以防意外情况。C语言基本单位是函数。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
这是没有保存的。保存后星号会消失。
关闭程序点close workspace。文件后缀为.c或者.cpp才可以用,当命名有.的时候就没有.C或者.CPP。否则就不能用了。
点编译后会产生阴影部分的图标。只有第一个是最关键的。只保存第一个就行了。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png
1CPU,内存条,硬盘,显卡,主板,显示器之间的关系。
一部电影的播放首先鼠标单击电影,操作系统会把硬盘上的数据调入内存条,(CPU无法直接处理硬盘上的数据)CPU可以处理内存条中的数据。处理完结果会把其中的数据变成图像声音。图像通过显示器显示出来。声音通过声卡显示出来。主板是把这些东西组织起来。(主板上面有很多插槽)
CPU到内存条有三条总线:控制,数据,地址。地址总线有32条2^32=4G
2Helloworld程序是怎样执行的:(cpu,内存条,VC++6.0操作系统之间的关系)
点击编译连接就生成了.exe程序。点击执行的时候会请求操作系统把硬盘上字符调入内存条中的,CPU处理内存条中的数据
3什么是数据类型:
基本类型数据(不能进行分割):
整数 : 整型 -- int -4
短整型 -- short int -2
长整型 -- long int -8
浮点数【实数】:
单精度浮点数--float【四个字节】
双精度浮点数--double【八个字节】
字符:单个字符--char -1
字符串--一系列字符的组合
复合类型数据:【由基本类型数据复合而来】
结构体
枚举(重点)
共用体
4什么是变量
变量的本质就是内存中一段存储空间。
5变量为什么必须得初始化(初始化就是赋值的意思)
C语言不赋值就会自动放入一个填充值。没有实际意义。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image005.png
6如何定义变量:
数据类型 变量名 = 要赋的值;
等价于
数据类型 变量名
变量名 = 要赋的值;
举例子:
int I = 3; 等价于 int i ; i = 3 ;
int I = 3 ; 等价于 int i ; int j ;
int I, j = 3 ; 等价于 int i
在汇编中: 在数字后面加字母B表示二进制数,加字母O表示八进制数,加字母D表示十进制数,加字母H表示十六进制数。
进制转换:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.png
C语言规定八进制前要加0(不是字母o),十六进制前要加0X或者0x,十进制前什么都不加!
%o表示以八进制输出
printf的用法
%d表示以十进制输出
%x或者%X表示以十六进制输出
%o表示以八进制输出
7常量在C语言中是如何表示的:
整数:
十进制: 传统的写法
十六进制: 前面加0x或0X
八进制: 前面0 注意是数字零不是字母o
浮点数(实数默认为double类型)
传统的写法
float x = 3.2;//
科学技术法
float x =3.2e3; //x的值是320
字符
8常量以什么样的二进制代码存储在计算机中:
整数是以补码的形式转化为二进制代码存储在计算机中的;
实数是以IEEE754标准转化为二进制代码存储在计算机中的;
字符的本质也是与整数的存储的方式相同。
ASCII码
代码规范化:
# include <stdio.h>
Int main(void)
{
retuin 0;
}
推荐书:林锐(高质量C /C++语言编程)
输入时,对齐。()先把这个括号输入齐了再敲。
一般程序三个步骤:
//定义变量
//对变量进行操作
//输出值
上面与下面代码功能不同时要换行。
运算级别最低的要空格。
什么是字节:
字节就是存储数据的单位,并且是硬件所能访问的最小单位。(一个字节等于八位)【int占四个字节long占八个字节char占一个字节一个C语言中字符占两个字节】
硬件上最小存储单位是位,但CPU只能控制到字节,通过位运算符可以控制到位。
不同类型数据之间相赋值的问题:(谭浩强C 程序教程P32各类型数据间的混合运算)
Int i = 45;
Long j = 102345;
I = j;
printf
Char ch =
“A”代表了'A' '\0' 单引号只能括单个字符,双引号括字符串。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image007.png
不能给C定义两次变量,所以 char ch = ‘B’是错误的,但是ch = ‘C’是正确的,这是把一个常数赋给ch相当于变量A。字符与字符串不能相互赋值。整形与长整形不能相互赋值。
什么是ASCII:
ASCII不是一个值,而是一种 规定,它规定了不同的字符是使用哪个整数值去表示。它规定了‘A’ -- 65 ‘B ’ -- 66
‘a’ -- 97 ‘b’ -- 98 ‘0’ -- 48
字符的存储【字符本质上与整数的存储方式相同】
基本的输入和输出函数的用法
printf ()再把输出【将变量的内容输出到显示器上】
四种用法:
1 printf (“字符串\n");【\n表示换行。】
2printf ("输出控制符",输出参数);
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.png
字母i=10输入的是二进制代码printf(“%d\n”,i)
中%d表示是把二进制代码以十进制输出所以必须要加来确定二进制编码格式。【 为什么需要输出控制符:
1 01组成的代码可以表示数据也可以表示指令
2如果01组成的代码表示的是数据的话,那么同样的01的代码组合以不同的输出格式输出就会有不同的输出结果。】
3printf(“输出控制符1 输出控制符2。。。”,输出参数1, 输出参数2, 。。。);
输出控制符和输出参数的个数必须一一对应
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image009.png
4printf(‘’输出控制符 非输出控制符“,输出参数);
百分号开头的基本都是输出控制符:
%d -- int
%ld -- long int
%c -- char
%f -- float
%lf -- double
%x(或者%x或者%#x) --int 或 long int 或 short int
%o -- 同上
%s --字符串
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.png
推荐使用第三个
小经验: 1写时间,功能,目的,用法。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image011.png
可以通过标记选中把结果复制过来。标记后再点击既是复制。
scanf ()[ 就是把键盘上输入的字符转化成一个数字赋给i变量]
两种用法:
用法一: scanf(“输入控制符”,输入参数);
功能: 将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。{C语言中输入控制符和输出控制符一样。}
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.png
用法二: scanf(“非输入控制符 输入控制符”, 输入参数);
功能: 将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。非输入控制符必须原样输入。
一次给多个变量键盘赋值:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image013.png
如何使用scanf编写出高质量代码
1使用scanf之前最好先使用printf提示用户以什么样的方式来输入【例如:scanf中有printf(“请输入i的值:”)】
2scanf中尽量不要使用非输入控制符,尤其是不要用\n
3应该编写代码对用户的非法输入做适当的处理【非重点】
char ch;
while ( (ch=getchar() ) != ' \n' )
continue
运算符:
算术运算符
+ - * /(除) %(取余数)
关系运算符
> >= < !=(不等于) ==(等于)
逻辑运算符【逻辑运算只能是真或假,在c中是1或0】
!(非) &&(并且) ||(或)
赋值运算符
= +=(A+=2等同于A=A+2) *= /= -=
优先级别:
算术>关系>逻辑>赋值
附录的一些琐碎的运算符知识:
自增 自减 三目运算符 逗号表达式
1自增【或者自减】
分类:
前自增--++i
后自增--i++
前自增和后自增的异同:
相同: 最终都使i加1
不同:前自增整体表达式的值是i加1之后的值,后自增整体的表达式的值是i加1之前的值。
为什么会出现自增:代码更精炼,自增的速度更快
学习自增要明白的几个问题:
1. 我们编程时要尽量屏蔽掉前后自增的区别
- 自增表达式最好不要作为一个更大的表达式的一部分来使用或者说
i++和++i单独成一个语句,不要把它作为一个完整的符合语句的一部分来使用。
如: int m = i++ + ++i + i + i++(不知道这个式子的顺序点【有三个,();】)
2三目运算符: ? :
A ? B : C
等价于
If (A)
B;
else
C;
3逗号表达式
格式
(A, B, C, D)
功能:
从左到右执行,最终表达式是最后一项的值。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image014.png
<img width="756" height="556" alt="计算机生成了可选文字: 测 试 取 模 运 算 符 的 例 子 # include int main(void) printf('%d %d %d %d %d % d 、 n , , 歹 / 1 , . 1 歹 / . 1 歹 . 1 歹 / 3 , 歹 司 ; return 亇 输 出 结 罘 是 ; . 13 3 

ress any key to continue 吉 : 取 / 。 的 运 算 对 象 必 须 是 整 鋭 结 果 是 后 的 余 数 , 其 余 刂 符 号 与 被 除 戮 相 同 14 , " src="file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image015.png">
C语言对真假的处理
非零是真
零是假
&&左边的表达式为假 右边的表达式不执行,||左边假右边还要执行。||左边是真不再执行。
不含分式的是表达式,含分式的是语句
流程控制:【使我们学习C语言的第一个重点】
1什么是流程控制
程序代码执行的顺序
2流程控制的分类
顺序
选择: 1if 2switch
循环 1for 2while 3 do…while
定义:某些代码可能执行,也可能不执行,有选择的执行某些代码。
if
1. if最简单的用法
格式:
if(表达式)
语句
功能:如果表达式为真,执行语句
如果表达式为假,语句不执行
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image016.png
2. if的范围问题:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image017.png
由此可见: if默认只能控制一个语句的执行或不执行,如果想控制多个语句的执行或不执行就必须把这些 语句用{}括起来。
3. if..else …的用法
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image018.png
这有两个语句,下面的printf最好和上面的语句分开。
else也是只能控制一个语句。所以CCCC总会输出。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image019.png 4. if..else if…else…的用法
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image020.png
从(1)开始,(1)正确A执行,(1)错误(2)正确执行B,(1)(2)错误(3)正确C执行。(1)(2)(3)错误,执行D。
5. C语言对真假的处理
非零是真,零就是假。真用1表示,假用零表示。
6. if举例--求分数的等级
100 ) pri 削 f 这 是 做 梦 ! \ (") 。 else if 〈 “ 。 re > = 90 score<=100) / / 不 能 写 成 90 < = “ 。 re 〈 = 100 printf(" 优 秀 ! № 0 , else if 〈 “ 。 re 〉 = 80 score<90) printf(" 良 好 0n0 , else if 〈 score 〉 = 60 score = 0 & score
对于90<=score<=100的解析:90<=score这是个逻辑值,要么真要么假,只能是零或一,所以<=100,所以表达式永远成立。
程序=算法加语言
一:互换数字:
int I = 3;
int j = 4;
int t;
t = I;
I = j;
j = t;
printf("I = %d, j = %d\n", I, j);
二:三个任意数字进行排序。
C语言常见误区:
1判断一个数字是否是素数
2判断一个数字是否是回文数(1221)
3编程实现求一个十进制数字的二进制形式
4把一个数字的每位是奇数的数字取出来组合形成的新数字
5求一个数字倒过来的数字
如何看懂一个程序: 1流程
2 每个语句的功能
3试数(把自己当计算机把流程走一遍。)
对一些小算法的程序:
1尝试自己去编程解决它,大部分人都无法自己解决,
2如果解决不了就看答案。关键是把答案看懂,这个要花很大的精力,也是我们学习的重点,
3看懂之后尝试自己去修改程序 ,并且知道修改之后程序的不同输出结果的含义。
4照着答案去敲。
5调试错误
6不要看答案,自己独立把答案敲出来。
7如果程序实在无法彻底理解,就把他背会。
强制类型转化
格式:
(数据类型)(表达式)
功能:
把表达式的值强制转化为前面所执行的数据类型。
浮点数的存储所带来的问题:
float和double都不能保证可以精确的存储一个小数。(3.454在电脑中可能是3.459999)
【C语言中默认一个小数是double类型,如果想要把这个数变为float必须在数字末尾加f或F】
举例:
1有一个浮点型变量X,如何判断X的值是否是零:
if(|x-0.000001|<=0.000001)
是零
else
不是零
2 为什么循环中更新的变量不能定义成浮点型
7. if的常见问题解析
1.空语句的问题
if (3 > 2);
等价于
if (3 > 2)
; //这是一个空语句
2. if (表达式1); if (表达式1)
A; A;
else else
B; B;
这是错误的 这是正确的
3if(表达式1)
A;
else if(表达式2)
B;
else if(表达式3)
C;
Else
D;
即使表达式1和表达式2都正确也只会执行A
4if(表达式1)
A;
else if(表达式2)
B;
else if(表达式3)
C;
这样写语法不会出错,但逻辑上有漏洞。
5
if(表达式1)
A;
else if(表达式2)
B;
else if(表达式3)
C;
Else (表达式4) //7行
D;
这样写是不对的,去掉(表达式4)或者在(表达式4)前面加if
6
if(表达式1)
A;
else if(表达式2)
B;
else if(表达式3)
C;
else (表达式4); //无实际意义的语句
D;
等价于
else
(表达式4) ; //无实际意义的语句
D;
switch:
电梯程序
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image022.png
val等于1的时候从case1开始执行。case、default是程序的入口,当遇到break程序结束,一旦进入一个入口其他入口就失效只有遇到break才会结束。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image023.png
常变量:只能被赋一个值的变量
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image024.png
循环:
定义:某些代码会被重复执行
分类: for
while
do…while
break和continue
for:
1格式:
for(1;2;3;)
语句A; (1-2-语句A-3)3完了算一个循环。
2执行的流程【重点】
单个for循环的使用
多个for循环的嵌套使用
1
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image025.jpg
总体来说只有两个语句,1和B。1-2-方框(4-5-A-6-5………………5不成立)-3【这是总的一次循环】-2…………直到2不成立执行B
2 for (1;2;3)
for(4;5;6)
{ A;
B;
}
整体是一个语句
3范围问题
4举例:
1+2+3+4+5+…………+100
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image026.png
先执行1,再执行2,再执行4,再执行3,再执行2,再执行4,再执行3………………直到2不成立结束。(++i表示是i+1)
for循环最简单的应用:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image027.png
int i;
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image028.png
1——2——4(正确)——5——6——3——2
1——2——4(错误)——6——3——2
1+ 1/2+1/3+………………+1/100:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image029.png
While
1.执行顺序
格式:
while(表达式)
语句;
(当表达式正确执行语句,直到表达式错误结束。)
2.与for的相互比较:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image030.png
3.举例
1从键盘输入一个数字,如果该数字是回文数,则返回yes,否则返回no
回文数:正着写,倒着写都一样,123 和12321
2菲波拉契序列
4.什么时候使用while,什么时候使用for
用多了就知道了、
do…while
格式:
do
{
…..
} while (表达式);
先执行内部语句然后判断表达式是否正确,正确再执行内部的语句。
do…while并不等价于for也不等价于while
主要是用于人机交互
break:
用于循环是用来终止循环
用于switch则是用来终止switch
不能直接用if,除非if属于循环内部的一个语句。
举例:
for (i=0; i<3; ++i)
{
if(3 > 2)
break; //break虽然是if内部的语句,但是它终止的是for循环
printf(“嘿嘿!\n”);
}
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image031.png
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image032.png
continue:
用于跳过本次循环余下的语句,转去判断是否需要执行下次循环。
for(1;2;3)
A;
continue
B;
1-2-A-3-2-A………………
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image033.png
输入完一个数字后再输入字符不会赋给j,只有点回车再输入才能赋给j
while里面式子表示只有输入回车才能结束while。
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image034.png
continue后会判断i是否 < 7
C语言到JavaSE到Java web到sql
数组:
为什么需要数组:
是为了解决大量同类型数据的存储和使用问题
为了模拟现实世界。
int a[5] = {1, 2, 3, 4, 5}; //a是数组的名字, 5表示数组元素的个数,并且这5个元素分别用a[0]a[1]a[2]a[3]a[4]表示。(a[0]为1.)
数组的分类: 一维数组、二位数组、多维数组、
一维数组 int a[5];
怎样定义一维数组:为n个变量连续分配存储空间,所有的变量数据类型必须相同,所有变量所占的字节大小必须相等。
例子:
int a[5];
有关一维数组的操作
初始化:
完全初始化
int a[5] = {1, 2, 3, 4, 5};
不完全初始化,未被初始化的元素自动为零
int a[5] = {1, 2, 3,};
不初始化,所有元素是垃圾值,
int a[5];
清零
int a[5] = {0};
错误写法:
int a[5];
a[5] = {1, 2, 3, 4, 5}; //错误只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的。除了定义数组的时候其它时候1,2,3,4,5代表下标即元素的位置。
int a[5] = {1, 2, 3, 4, 5};
a[5] = 100; // 错误 因为没有a[5]这个元素最大到a[4]
int a[5] = {1, 2, 3, 4, 5};
int b[5];
如果要把a数组中的值全部复制给b数组
错误的写法:
b = a; //错误a不代表数组的五个元素,只代表第一个元素的地址
正确的写法 : for (i=0; i<5; ++i)
b = a
赋值
排序
求最大/小值
倒置
查找
插入
删除
二维数组
int a[3][4]
总共是12个元素,可以当做3行4列看待,这12个元素的名字依次是:
a[0][0]a[0][1]a[0][2]a[0][3]
a[1][0]a[1][1]a[1][2]a[1][3]
a[2][0]a[2][1]a[2][2]a[2][3]
a[j];表示第i+1行第j+1列的元素
int a[m][n]; 该二维数组右下角位置的元素只能是a[m-1][n-1]
初始化:
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int a[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
操作
输出二维数组内容:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image035.png
对二维数组排序
求每一行的最大值
判断矩阵是否对称
多维数组 是否存在多维数组:不存在,因为内存是线性一维的,n维数组可以当做每个元素是n-1维数组的一维数组。
比如:
int a[3][4]:该数组是含有3个元素的一维数组,只不过每个元素都可以再分成4个小元素。
int a[3][4][5]:该数组是含有3个元素的一维数组,只不过每个元素都是4行5列的二维数组。
函数【C语言的第二个重点】:
在函数内部的变量只在本函数内部使用
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image036.png
为什么需要函数
1避免了重复性操作2有利于程序的模块化
什么叫做函数【看文件夹中的举例2】
逻辑上:能够完成特定功能的独立的代码块
物理上:
能够接受数据[也可以不接受数据],
能够对接受的数据进行处理。
能够对数据处理的结果返回[当然也可以不返回任何值]
总结:函数是个工具,他是为了解决大量类似问题而设计的
函数可以当做一个黑匣子(不知道内部源码)
如何定义函数
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
1函数定义的本质是详细描述函数之所以能够
实现某个特定功能的具体方法
2 return 表达式; 的含义:
1 终止被调函数向主调函数返回表达式的值
2 如果表达式为空, 则只终止函数,不向主调函数返回任何值
3 break是用来终止循环和switch的,return是用来终止函数的
例子:
void f()
{
return; //return只用来终止函数,不向主调函数返回任何值
}
Int f()
{
return 10; //向主调函数返回10
}
3 函数返回值的类型也称为函数的类型,因为如果函数名前的返回值类型
和函数执行体中的return 表达式; 中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型 为准【看文件夹中的举例3,4】
函数的分类
有参函数 和 无参函数(无参最好用(void)表示)
有返回值 和 没有返回值
库函数 和 用户自定函数
值传递函数 和 地址传递函数
普通函数 和 主函数(main函数)
一个程序必须有一个主函数
主函数可以调用普通函数 普通函数不能调用主函数
普通函数可以相互调用
主函数是程序的入口,也是程序的出口
注意的问题
函数调用和函数定义的顺序
如果函数调用写在了函数定义的前面,则必须加函数前置声明(可以不加形参)
函数前置声明:
1告诉编译器即将出现的若干个字母代表的是一个函数
2告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况
3函数声明是一个语句,末尾必须加分号【举例5】
4对库函数的声明是通过 # include <库函数所在的文件的名字.h>来实现的 (stdio表示标准的输入输出文件。 .h表示头文件。)
形参和实参(实际参数):【调用语句中与形参对应的】
个数相同。 位置一 一对应 数据类型必须相互兼容
如何在软件开发中合理的设计函数来解决实际问题:
只用main函数实现,有局限性1代码重用性不高2代码不容易理解
一个函数功能尽量独立,可开发性强【看例子】
函数是C语言的基本单位,类是Java,C#,C++的基本单位
常用的系统函数:
double sqrt(double x);
求x的平方根
int abs(int x)
求x的绝对值
double fabs(double x)
求x的绝对值
专题:(以后学,参见郝斌数据结构视频,先搞懂栈)
递归:A调用A
栈:所有先进后出的
变量的作用域和存储方式:
按作用域分: 全局变量: 在所有函数外部定义的变量
使用范围:从定义位置开始到整个程序结束。
局部变量:在一个函数内部定义的变量或函数的形参
适用范围: 只能在本函数内部使用。
注意的问题: 全局变量和局部变量命名冲突问题
在一个函数内部如果定义局部变量名字和全局变量名一样时,局部变量会屏蔽掉全局变量。
按变量的存储方式:
静态变量
自动变量
寄存器变量
指针:表示一些复杂的数据结构、快速的传递数据减少内存的使用【重点】,使函数返回一个以上的值【重点】,能直接访问硬件,能够方便的处理字符串,是理解面向对象语言中引用的基础 总结:指针是C语言的灵魂
指针就是地址,地址就是内存单元的编号,指针变量是存放地址的变量。指针和指针变量是两个不同的概念。但是通常我们叙述是会把指针变量简称为指针实际他们的含义并不一样。
指针的定义
地址
内存单元的编号,从零开始的非负整数,范围4G【0——4G-1】
指针: 就是地址,地址就是内存单元的编号,指针变量是存放地址的变量。指针和指针变量是两个不同的概念。但是通常我们叙述是会把指针变量简称为指针实际他们的含义并不一样。指针本质就是一个操作受限的非负整数。
指针的分类
1基本类型指针【重点】
int * p; //p是变量的名字,int * 表示p变量存放的是int类型变量的地址
//int*p ;应该理解为p是变量名,p变量的数据类型为int*
所谓int*类型实际就是存放int变量地址的类型
int I = 3;
p = &I; // 1p保留了i的地址,因此p指向i,
2p不是i,修改p的值不影响i的值修改i的值也不影响p的值。
3如果一个指针变量指向了某个 普通变量,则*指针变量就完全等同于普通变量
例子: 如果p是个指针变量,并且存放了普通变量i的地址则p指向了普通变量I
*p就完全等同于i或者说:在所有出现*p的地方都可以替换成I
在所有出现i的地方都可以替换成*p
指针常见错误:
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image037.png
经典指针程序:看程序。
*的三个含义:1,乘法
2,定义指针变量int * p;//定义了一个名字叫p的变量,
int *表示p只能存放整形变量的地址。
3,指针运算符:
该运算符放在已经定义好的指针变量的前面
如果p是一个已经定义好的指针变量
则 *p表示 以p的内容为地址的变量
如何通过被调函数修改主调函数普通变量的值
1实参必须为该普通变量的地址
2形参必须为指针变量
3在被调函数中通过 *形参名 = ….的方式就可以修改主调函数相关变量的值
2指针和数组
指针和一维数组
一维数组名:
一维数组名就是指针常量,
它存放的是一维数组第一个元素的地址。【看例子】
下标和指针的关系
如果p是个指针变量,则p永远等价于*(p+i)
确定一个一维数组需要几个参数【如果一个函数要处理一个一维数 组,则需要接收该数组的哪些信息】
需要两个参数:1 数组第一个元素的地址 2数组的长度
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image038.png
指针变量的运算
指针变量不能相加,相乘,相除。
如果两个指针变量指向的是同一块空间中的不同存储单元
则这两个指针变量才可以相减【看例子】
一个指针变量到底占几个字节:4个
预备知识: sizeof(数据类型)
功能:返回值就是该数据类型所占的字节
例子: sizeof(int) = 4
总结:一个指针变量无论它指向的变量占几个字节,它只占4个
一个变量的地址使用该变量首字节的地址来表示
指针和二维数组
3指针和函数
4指针和结构体【重点】
5多级指针【看例子】
专题:
动态内存分配【重点,难点】
传统数组的缺点:
1数组长度必须事先制定,且只能是常整数,不能是变量
例子: int a[5]; //ok
int len = 5; int a[len]; //error
2 传统形式定义的数组,该数组的内存程序员无法手动释放
数组一旦定义,系统为该数组分配存储空间就会一直存在
除非数组所在的函数运行结束
在一个函数运期间,系统为该函数中数组所分配的空间会一直
存在,直到该函数运行完毕时,数组的空间才会被系统释放
3数组的长度一旦定义,其长度就不能再更改
数组的长度不能在函数运行的过程中动态的扩充或缩小
4 A函数定义的数组,在A函数运行期间可以被其他函数使用
但A函数运行完毕后,A函数中的数组将无法再被其他函数使用。
传统方式定义的数组不能跨函数使用
为什么需要动态内存
动态数组很好地解决传统数组的这四个缺陷
传统数组也叫静态数组
动态内存分配举例_动态数组的构造(看动态一维数组例子)
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image039.png
<img width="879" height="410" alt='计算机生成了可选文字: # include # include 〈 a110c . h) void 0 ( i * q) = 200 ; //error = 200 , //**q = 200 : //error *q = 200 //free (q) ; / / 把 q 所 指 向 的 内 存 释 放 掉 int maln (void) (int *)åiåiGé(sizeof(int)) Int * p . 本 语 句 跹 须 的 主 释 掉 , . 否 刂 会 . 导 荔 攵 第 20 彳 亇 的 代 码 出 / / sizeof ( int) 三 飞 回 值 . 地 int 斤 占 的 字 . 节 , *p = 10 , printf("%d\n", (p) , / / 10 f (p) , //p*int * 类 型 printf("%d\n", (p) , / / 200 弟 . 20 行 ' src="file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image040.png">
静态内存和动态内存的比较
静态内存是由系统自动分配,由系统自动释放
静态内存是在栈分配的
动态内存是由程序员手动分配,手动释放
动态内存实在堆分配的
跨函数使用内存的问题
静态内存不能跨函数,动态内存可以
结构体:(重点)
为什么需要结构体:为了表示一些复杂的事物,而普通的基本类型无法满足实际要求
什么叫结构体:把一些基本类型数据组合在一起形成的新的复合数据类型
如何定义一个结构体:三种方式,推荐使用第一种
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image041.png
// 第三种方式
struct
{
int age;
float score;
Char sex;
} st3;
Int main(void)
{
struct Student st = {80, 66.6, 'f'}; //st是我们定义的变量
}
怎样使用结构体变量
赋值和初始化
定义的同时可以整体赋初值【初始化】 struct Student st = {80, 66.6, 'f'};
如果定义完之后,则只能单个赋处值st.age = 10; st.score =88;
如何取出结构体变量中的每一个成员
1. 结构体变量名.成员名(先编译一下,然后st. 成员名会直接出来)
2.指针变量名->成员名 【在计算机内部会被转化成(*指针变量名).成员名的方式来执行。】
age = 88 ; / / 第 二 种 方 式 st . score = 66 . 6f 《 / / 忄 苇 . 一 种 方 式 printf ("96d %f\n" st. age, pst— 〉 score) · 愆 义 白 0 同 时 丿 武 衤 刀 •t 就 " src="file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image042.png">
结构体变量和结构体指针变量作为函数参数传递的问题【看例子】
推荐使用结构体指针变量作为函数参数来传递
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image043.png
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image044.png
结构体变量的运算
结构体变量不能相加,相减,也不能相互乘除,但结构体变量可以相互赋值。
struct Student
{
int age;
char sex;
char name[100];
};
struct Student st1, st2;
st1+st2 st1*st2 st1/st2 都是错误的
st1 = st2 或者st2 =st1 都是正确的
举例【看例子】
动态构造存放学生信息的结构体数组
动态构造一个数组,存放学生信息
然后按分数排序输出
枚举【看例子】
什么是枚举
把一个事物所有可能的取值一 一列举出来
怎样使用枚举
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image045.png
从Monday开始一次代表0123.Monday后面有=n的话从n开始依次…………
而且Wednesday不能替换成2
枚举的优缺点
代码更安全,直观但书写麻烦。
位运算符:
& — —按位于 &&逻辑与 也叫并且,&&与&(二进制每个取与) 的含义完全不同
| 按位或
~ 按位取反
^ 按位异或相同为零不同为1 1^0 = 1 0^1 = 1 1^1 =0 0|0 = 0
<< 按位左移 i<<1表示把i的所有二进制位左移一位,右边补零左移n位相当于乘2的n次方
>> 按位右移 i>>1表示把i的所有二进制位右移一位,右移n位相当于除以2的n次方左边一般是0,也可能1
(前提数据不能丢失)
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image046.png
位运算符的现实意义:
通过位运算符我们可以对数据的操作精确到每一位
专题
补码:
原码:也叫符号-绝对值码
最高位0表示正 1表示负 ,其余二进制位是该数字的绝对值的二进制位
原码简单易懂,但加减乘除四种运算,增加了cpu的复杂度,零的表示不唯一。
反码
反码运算不便。也没有在计算机中应用
移码
移码表示数值平移n位,n称为移码量。
移码主要用于浮点数的阶码的存储
补码:(计算机内部所有的整数都是以补码的形式来存储的)
十进制转二进制
正整数转二进制(5的二进制为0101)
除2取余,直至商为零,余数倒叙排序
负整数转二进制
先求与该负数相对应的正整数的二进制代码,然后将所有位取反
末尾加1,不够位数时(看是什么类型),左边补1
零转二进制
全是零
二进制转十进制
如果首位是0,则表明是正整数,按普通方法来
如果首位是1, 则表明是负整数,将所有位取反,末尾加1,所得数字就是该负数的绝对
学习目标:
在VC++6.0中一个int类型的变量所能存储的数字范围是多少
int类型变量所能存储的最大正数用十六进制表示是:7FFFFFFF
int类型变量所能存储的绝对值最大的负整数用16进制表示:80000000
绝对值最小负数的二进制代码是多少
最大正数的二进制代码是多少
已知一个整数的二进制代码求出原始数字
数字超过最大正数会怎样
不同类型数据的相互转化
进制转化:
字符串的处理:
链表:
算法
通俗的算法: 解题的方法和步骤
狭义的算法: 对存储数据的操作,对不同的存储结果要完成某一个功能所执行的操作是不一样的
比如:要输出数组中所有元素的操作和要输出链表中所有元素的操作肯定是不一样的
这说明:算法是依附于存储结构的,不同的存储结构所执行的算法是不一样的
广义的算法:广义的算法也叫泛型(无论数据是如何存储的,对该数据的操作都是一样的)
我们可以通过两种结构来存储数据:
1数组:
优点:存取速度快
缺点:需要一个连续很大的内存,插入和删除元素的效率很低
2 链表:
优点:插入删除效率很高,不需要一个很大的存储空间
缺点: 查找某个位置的元素效率很低
专业术语:
头结点:
头结点的数据类型和首节点的类型是一样的
头结点是首节点前面的的那个节点
头结点并不存放有效数据
设置头结点的目的是为了方便对链表的操作
头指针:
存放头结点地址的指针变量
首节点
存放第一个有效数据的节点
尾节点
存放最后一个有效数据的节点
确定一个链表需要一个参数
头指针
二进制全部为零的含义:— —000000000000000
1数值零
2字符串结束标记符‘\0’
3空指针NULL
NULL表示的是零,而这个零不代表数字零,而表示的是内存单元的编号零
我们计算机规定了,以零为编号的存储单元的内容不可读,不可写