C语言自学笔记

C语言学习

第一周:

人:What to do
计算机: How to do

计算机语言

  1. 程序是用特殊的编程语言写出来表达如何解决问题的。
  2. 不是用来和计算机交谈,而是描述要求它如何做事情的过程和方法。

算法

  • 我们要让计算机做计算,就要想出来它的计算步骤,然后用编程语言写出来
  • 计算机做的所有事情都叫做计算
  • 计算的步骤就是算法

程序的执行

  • 解释:借助一个程序,那个程序能试图理解你的程序,然后按照你的要求执行
  • 编译:借助一个程序,就像一个翻译,把你的程序翻译成计算机真正能懂的语言-----机器语言-------写的程序,然后,这个机器语言写的程序就能直接执行了。

C语言

  • C语言是从B语言发展而来的,B语言是从BCPL发展而来的,BCPL是从FORTRAN发展而来的。
  • BCPL和B都支持指针间接方式,所以C也支持了
  • C语言还受到了PL/I的影响,还和PDP-11的机器语言有很大关系
  • 1973年3月,第三版的Unix上出现了C语言的编译器
  • 1973年11月,第四版的Unix(System Four)发布了,这个版本是完全用C语言重新写的。

C语言用在哪里

  • 操作系统
  • 嵌入式系统
  • 驱动程序
  • 底层驱动
  • 图形引擎、图像处理、声音效果
  • 开发效率>>学习过程
  • 开发效率>>开发乐趣
  • 日常应用很少直接用C语言编写
  • 学习C语言的过程主要是练习写代码
  • 而非真实的软件

编译---->运行

  • C语言需要被编译才能运行,所以你需要
    编辑器
    编译器
  • 或者·,IDE(集成开发环境)

第二周:
做计算

printf("23+43=%d\n",23+43);

算找零钱

需要:

 - 有地方放输入的数字
 - 有办法输入数字
 - 输入的数字能参与计算
如何能在程序运行时,输入那个数字 23  ,然后计算输出结果?

int price=0;
prinf("请输入金额(元):");
scanf("%d",&price);
int change=100-price;
printf("找您零钱为:%d",change);

变量

  • int price=0;
  • 这一行定义了一个变量。变量的名字是price ,类型是 int ,初始值是 0
  • 变量是一个保存数据的地方,当我们需要在程序中保存数据时,比如上面的例子中,要记录用户输入的价格,就需要一个变量来保存他,用一个变量保存了数据,它才能参与到后面的计算中,比如算找零钱。

变量的定义

  • 变量定义的一般格式为:
  • < 类型名称 > < 变量名称 >;
  • int price;
  • int amount;
  • int price,amount;

变量的名字

  • 变量需要一个名字,变量的名字是一种“标识符”,意思是它是用来识别这个和那个的不同的名字
  • 标识符有标识符的构造规则,基本的组成是:标识符只能由字母、数字、下划线组成,数字不能出现在第一个位置上,C语言的关键字不可以作为标识符。

C语言的关键字(部分)

auto,break,case,char,const,continue,default,do,double,else
enum,extern,float,for,goto,if,int,long,register,return,short
signed,sizeof,static,struct,switch,typedef,union,unsigned,void
volatile,while,inline 

赋值和初始化

  • int price=0;
  • 这一行,定义了一个变量。变量的名字是 price ,类型是 int ,初始值是 0
  • price =0 是一个式子,这里的“=”,是一个赋值运算符,表示将“=”,右边的值赋给左边的变量

赋值

  • 和数学不同,a=b,在数学中表示关系,既a和b的值一样;而在程序设计中,a=b表示计算机做一个动作:将b的值赋值给a。关系是静态的,而动作是动态的。在数学中,a=b和b=a是完全相同的,而在程序设计中,两者的意思完全相反。

读整数

  • scanf("%d",&price);
  • 要求scanf函数读入下一个整数,读到的结果赋值给变量price
  • 小心price前面的&

常量

  • int change=100;
  • 固定不变的数,是常数。直接写在程序里面,我们称之为直接量(literal)
  • 更好的方式,是定义一个常量。
  • const int AMOUNT=100;
  • 要在C99里面
#include <stdio.h>
int main()
{
const int AMOUNT=100;
int price=0;
printf("请输入金额(元):");
scanf("%d",&price);
int change=AMOUNT-price;
printf("找您%d元。",change);
return 0;
}

const

  • const是一个修饰符,加在int的前面,用来给这个变量加上一个const(不变的)的属性。这个const的属性表示这个变量的值一旦被初始化,就不能在修改了。
  • int change = AMOUNT-price;
  • 如果你试图对常量进行修改,把它放在赋值运算符左边,就会被编译器发现,指出为一个错误。

浮点数

  • 带小数点的数值,浮点数这个词的本意就是指小数点是浮动的,是计算机内部表示非整数(包含分数和无理数)的一种方式,另一种叫做定点数,不过在C语言中,你不会遇到定点数。人们接用浮点数这个词来代表所有的带小数点的数。

double

  • double的意思就是双,它本来是“双精度浮点数”的第一个单词,人们用来表示浮点数类型。除了double还有float,(意思就是浮点!)表示单精度浮点数。
  • float:单精度浮点数
  • double:双精度浮点数

数据类型

  • 整数
  • int
  • printf(“%d”,…);
  • scanf("%d",…);
  • 带小数点的数
  • double
  • printf(“%f”,…);
  • printf("%lf",…);

表达式

  • 一个表达式时一系列运算符和算子的组合,用来计算一个值。
  • amount=x*(1+0.0003)(1+0.33)(2+5.6621);
  • total=57;
  • count=count+1;

运算符

  • 运算符(operator)是指进行运算的动作,比如加法运算符“+”,减法运算符“-”
  • 算子(operand)是指参与运算的值,这个值可能是常数,也可能是变量,还可能是一个方法的返回值。
  • ++ :自增运算符
  • – :自减运算符
  • & :取地址运算符
  • ! :逻辑非运算符

计算时间差

int hour1,minute1;
int hour2,minute2;
scanf("%d %d",&hour1,&minute1);
scanf("%d %d",&hour2,&minute2);
int t1=hour1*60+minute1;
int t2=hour2*60+minute2;
int t=t1-t2;
printf("时间差是%d小时%d分",t/60,t%60);

运算符优先级

优先级运算符运算结合关系举例
1+单目不变自右向左a*+b
1单目取反自右向左a*-b
2*自左向右a*b
2/自左向右a/b
2%取余自左向右a%b
3+自左向右a+b
3自左向右a-b
4=赋值自右向左a=b

赋值运算符

  • 赋值也是运算,也有结果
  • a=6的结果是a被赋予的值,也就是6
  • a=b=6 等价于 a=(b=6)

交换两个变量

  • 如果已经有
  • int a=6;
  • int b=5;
  • 如何交换a、b两个变量的值?

程序是按步执行的

  • 程序表达的是顺序执行的结果,而不是关系
  • a=b;
  • b=a;
  • 是依次执行的,结果使得a和b都得到b原来的值

复合赋值

  • 5个算是运算符 + - * / % ,可以和赋值运算符 “ = ”,结合起来,形成复合赋值运算符 += -= *= /= %=
  • total+=5;
  • total=total+5;
  • 注意两个运算符中间不要有空格。

递增递减运算符

  • ++ 和 - - 是两个很特殊的运算符,他们是单目运算符,这个算子还必须是变量。这两个运算符分别叫做,递增和递减运算符。他们的作用就是给这个变量+1或者-1
  • count++;
  • count–;
  • count=count+1;

自增运算符前缀后缀

  • ++ - - 可以放在变量的前面,叫做前缀形式,也可以放在变量的后面,叫做后缀形式。
  • 无论是前缀或者后缀,都是使得自己本身的值加一或者减一

第三周
条件

  • 计算两个值之间的关系就叫做 关系运算
  • 常见的关系运算符
  • ==
  • !=
  • <
  • <=

关系运算的结果

  • 当两个值符合关系运算符的预期时,关系运算的结果为 1 ,否则为0
printf("%d\n",5==3);
printf("%d\n",3>5);

练习:找零计算器

int price=0;
int bill=0;
printf("请输入金额(元)");
scanf("%d",&price)
printf("请输入票面(元)");
scanf("%d",&bill);
printf("应该找您:%d 元",bill-price);

注释

  • 注释插入在程序代码中,用来向读者提供解释信息,它们对于程序的功能没有任何影响,但是往往能使得程序更容易被人类读者理解。

if语句

  • 判断大小
  • 方案1
int a,b;
printf("请输入两个整数");
scanf("%d %d",&a,&b);
int max=0;
if(a>b){
max=a;
}
if(b>a){
max=b;
}
printf("最大的那个数是 %d",max);
  • 方案2
int a,b;
printf("请输入两个整数");
scanf("%d %d",&a,&b);
int max=0;
if(a>b){
max=a;
}else{
max=b;
}
printf("最大得那个数是 %d",max);
  • 方案3
int a,b;
printf("请输入两个整数");
scanf("%d %d",&a,&b);
int max=b;
if(a>b){
max=a;
}
printf("最大的那个是%d",max);
  • 一个基本的if语句由一个关键字 if 开头,跟上在括号里的一个表示条件的逻辑表达式,然后是一对大括号“{ }”,之间的若干条语句。如果表示条件的逻辑表达式的结果不是0,那么就执行跟着括号里面的若干条语句,否则就跳过这些语句,不执行,而继续执行下面的语句。
  • 练习输入成绩,给成绩分等级。

嵌套的判断

  • 当 if 的条件满足或者不满足的时候要执行的语句,也可以是一条 if 或者if - else语句,这就是嵌套的 if 语句。

else的匹配问题

  • else总是和最近的那个 if 匹配
  • 缩进格式不能暗示else的匹配
  • 好习惯:在 if 或者 else 后面总是有{ },即使只有一条语句。
  • 练习级联的 else-if

if 常见的错误

  • 忘了大括号
  • if 后面加了分号
  • 错误使用 == 和 =
  • 使人困惑的 else

代码风格

  • 在if 和 else后面必须加上大括号形成语句块
  • 大括号内的语句缩进一个 tab 的位置

switch-case

  • 练习玩级联的判断成绩等级 使用if语句之后
  • 使用switch 实现多分支。
switch(type){
case 1:
printf("您好");
break;
case 2:
printf("您真棒");
break;
}
  • 控制表达式只能是整数型的结果
  • 常量可以是常数,也可以是常数计算的表达式

break

  • switch语句可以看作是一种基于计算的跳转,计算控制表达式的值后,程序会跳转到相匹配的case处,分支标号只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果后面没有break,就会顺序执行到下面的case里去,直到遇到一个break,或者指导switch 语句结束为止。

第四、五周
循环

  • for 循环
  • for ( ; ; ){ }
  • while ( 真或者假 ) { }
  • do { }while( 真或者假)
  • do-while循环和while循环很像,区别是,循环体至少执行的次数,也跟条件判断的位置来决定的,while循环,进入循环体之前就进行了判断,所以执行次数最少为 1 次,而 do-while循环,是先进入循环体,然后在判断,所以循环体执行的次数最少为1 次。

如何选择循环

  • 如果有固定的循环次数,用 for
  • 如果必须执行一次,用do-while
  • 其他情况用while

练习猜数游戏

  • 让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉他输入是大了还是小了,指导用户猜对为止,最后还要告诉用户总共猜了多少次。
  • 因为需要循环让用户进行猜测,所以用到循环。
  • 核心的重点是循环的条件。
1、计算机随机想一个数,记在变量number里
2、一个负责统计次数的变量account 初始化为0
3、让用户输入一个数字a
4、account自增
5、判断a和number是否相等,如果大就说大,小就说小,相等就跳出循环

随机数

  • 每次召唤 rand() 就得到一个随机的整数

练习整数的逆序输出
练习用for循环写一个阶乘

break和continue

  • break:跳出循环
  • continue:结束本次循环,进入下一次循环
  • 都只能对它所在的那一层去做
  • 可以使用goto语句来跳出多重循环

循环的嵌套

  • 练习输出100以内所有的素数
  • 循环里面又有循环成为循环嵌套

第六周
C语言是有类型的语言

  • C语言的变量必须在使用之前定义,并且确定类型

C语言的类型

  • 整数
    *char 、short 、int、long、long long
  • 浮点数
    *float、double、long double
  • 逻辑
    *bool
  • 指针
  • 自定义类型

类型有何不同

  • 类型名称:int、long、double
  • 输入输出时候的格式化:%d、%ld、%lf
  • 所表达的范围:char<short<int<float<double
  • 内存中所占据的大小:1个字节到16个字节
  • 内存中表达的形式:二进制(补码)、编码

sizeof

  • 是一个运算符,可以给出某个类型或者某个变量在内存中所占据的字节数
  • sizeof(int)
  • sizeof(i)

整数的范围

  • char 1字节 -128~~127
  • short 2字节 -32768~~32767
  • int 取决于编译器,通常的意义是“1个”字
  • long 4个字节
  • long long 8个字节

8进制和16进制

  • 一个以0开始的数字字面量是8进制
  • 一个以0x开始的数字字面量是16进制
  • %o 用于8进值,%x用于16进值

浮点类型

类型字长有效数字
float327
double6415

浮点的输入输出

类型scanfprintf
float%f%f
double%lf%f

输出的精度

  • 在% 和f之间加上 .n 可以指定小数点后几位,这样的输出是做4舍5入的

超过范围的浮点数

  • printf输出 inf 表示超过范围的浮点数
  • printf输出 nan 表示不存在的浮点数

浮点运算的精度

  • 带小数点的字面量是double而不是float
  • float需要用f或者F后来点缀表明身份

选择浮点类型

  • 如果没有特殊需要,直接用double
  • 现代cpu能够轻松胜任

字符类型

  • char是一种整数,也是一种特殊的类型:字符,这是因为,用单引号表示的字符字面量 ’ a ‘ ,’ 1 ‘
  • ’ ‘也是一个字符
  • printf和scanf里面用%c来输入输出字符

逃逸字符

字符意义字符意义
\b回退一格"双引号
\t到下一个表格为=位\ ’单引号
\n换行\ \反斜杠本身
\r回车

自动类型转换

  • 当运算符的两边出现不一样的类型时,会自动转换成较大的类型
  • 大的意思是能表达的数的范围更大
  • char --》short----》int-----》long----》long long
  • int----》float-----》double

强制类型转换

  • 要把一个量强制转换成另一个类型,需要:
  • (类型)值

bool

  • #include < stdbool.h>
  • 之后就可以使用bool和true、false

逻辑运算

  • 逻辑运算是对逻辑量进行的运算,结果只有0或1
  • 逻辑量是关系运算或逻辑运算的结果
运算符描述示例结果
逻辑非!a如果a是true则结果为false
&&逻辑与a&&ba和b必须都是true才能是true
逻辑或

表达在4和6之间

  • 错误
    *4<x<6
  • 正确
    *x>4&&x<6

优先级

  • !> && > 逻辑或

短路

  • 逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算。

条件运算符

  • count=(count>20)?count-10 : count+10;
  • 条件、条件满足时候的值、条件不满足时候的值

逗号运算符

  • (a+b,b+c,c+d)

第7周:
什么是函数

  • 函数是一块代码,接收零个或者多个参数,做一件事情,并返回零个或一个值

调用函数

  • 函数名(参数值);
  • ()起到函数调用的重要作用
  • 即使没有参数也需要()
  • 如果有参数,则需要给出正确的数量和顺序
  • 这些值会被按照顺序,依次用来初始化函数中的参数

从函数中返回值

  • return 停止函数的执行,并返回一个值
  • return ;
  • return 表达式;
  • 一个函数里,可以出现多个return 语句

没有返回值的函数

  • void 函数名(参数表)
  • 不能使用带值得return
  • 可以没有return
  • 调用的时候不能做返回值的赋值

函数的先后关系

  • 像这样把sum()写在上面,是因为:
  • C语言的编译器自上而下顺序分析你的代码

函数原型

  • 函数头,以分号结尾构成了函数的原型
  • 函数原型的目的是告诉编译器这个函数长什么样
  • 名称
  • 参数(数量及类型)
  • 返回类型

类型不匹配

  • 调用函数时给的值与参数的类型不匹配,是C语言传统上的最大的漏洞
  • 编译器总是悄悄地替你把类型转换好,但这可能不是你所期望的

交换 a 和 b的值

  • 用函数交换 a 和 b的值

传值

  • 每个函数有自己的变量空间,参数也位于这个独立的空间中,和其他函数没有关系
  • 对于参数表中的参数,叫做“形式参数”,调用函数时候给的值,叫做“实际参数”

本地变量

  • 函数的每次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作本地变量
  • 定义在函数内部的变量就是本地变量
  • 参数也是本地变量
  • 也叫做局部变量

变量的生存期和作用域

  • 生存期:什么时候这个变量出现了,到什么时候这个变量消亡了
  • 作用域:在什么范围内可以访问这个变量

本地变量的规则

  • 本地变量是定义在块内
    *可以定义在函数的块内
    *也可以定义在语句的块内
    *甚至可以随便拉一个大括号来定义本地变量
  • 程序进入这个块之前,其中的变量不存在,离开这个块,其中的变量就消失了
  • 块外面定义的变量在里面仍然有效
  • 块里面定义的了和外面同名的变量,则掩盖外面的
  • 不能在同一个块里面定义同名的变量
  • 本地变量不会被默认初始化

函数里的函数?

  • C语言不允许嵌套函数

第八周
如何记录很多数?

  • 数组
  • int number[100];
  • scanf("%d",&number[ i ]);

定义数组

  • < 类型> 变量名称【元素数量】
  • int grades[100];
  • double weight[100];
  • 元素数量必须是整数

数组

  • 是一种容器(放东西的东西),特点是其中元素具有相同的数据类型一旦创建就不能改变大小
  • 数组的元素在内存中是连续依次排列的

数组的单元

  • 数组的每个单元就是数组类型的一个变量
  • 使用数组时放在【】中的数字叫做下标或索引,下标从0开始计数
  • garde[0]
  • grade[1]

计算数组的大小

  • sizeof(a)/sizeof(a[0])

第九周

指针

  • &是一个运算符,是用来获得变量的地址,它的操作数必须是变量
  • 就是保存地址的变量

指针变量

  • 变量的值是内存的地址
  • 普通变量的值是实际的值
  • 指针变量的值是具有实际变量值的地址

数组变量是特殊的指针

  • 数组变量本身表达地址,所以
  • int a[10] ; int *p=a ; 不需用&

指针是const

  • 表示一旦得到了某个变量的地址,不能在指向其他变量

指针的类型转换

  • void *表示不知道指向什么东西的指针
  • 指针也可以转换类型

第十周

字符串

  • 字符数组
  • char word [ ]={‘H’,‘e’,‘l’,‘l’,‘o’}
  • 上面不是字符串,而是字符数组
  • 字符串; char word [ ]={‘H’,‘e’,‘l’,‘l’,‘o’,’\0’}
  • 字符串是以0结尾的一串字符
  • 字符串以数组的形式存在,以数组或者指针的形式访问
  • string.h 头文件里面有很多处理字符串的函数
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值