#include
int main ()
{
printf("欢迎大家学习C语言!\n"); //\n为换行
return 0;
}
理论:理论知识 多思考
上机:上机练习
多敲程序,多犯错误,将来即便犯错也知道哪里出错
目标:能看懂程序,能调试程序,自学能力很重要
学C就是学Java,因为C语言至少80%的语法知识都被Java继承过来了
C是面向过程语言的代表,学好C有助于学习Java中面向对象的思想。
学好C中的指针是理解Java中引用的基础!如果不懂指针就不可能对Java中的引用有深刻的理解,而引用是Java中一个最基本但又十分重要的概念。
需要底层的专业知识
懂英语有助于学习,但不懂也不会影响
数学:数学函数和C语言的函数本质思想是一样的,但在表面上看没有任何关系
C语言研究高深算法才会用到数学
由系统定义,不能用做其他定义
auto(自动的) break(破坏,终止) case(案例)
char(C语言中char用于定义字符类型变量或字符指针变量)
const(常量:常数,恒定不变的值) continue(继续)
default(默认) do(做) double(双) else(否则)
enum(枚举数据类型) extern(额外的) float(浮点型)
for(为了) goto(去) if(如果) int(定义整数数据的标识符)
long(长) register(寄存器) return(返回) short(短)
signed(有符号的) sizeof(运算符) static(静态变量)
struct(结构体) unsigned(无符号的) union(联合;一个单元)
switch(专门用于处理分支结构的条件选择语句,Switch语句又名开关语句)
typedef(用来为复杂的声明定义简单的别名)
void(无类型) volatile(易变的) while(当)
C语言的简介(1讲)
第一讲、基本编程知识(1讲)
第二讲、数据类型(1讲)
第三讲、运算符和表达式(1讲)
第四讲、流程控制(4讲)(重要)
第五讲、函数(2讲)(重要)
第六讲、数组(1讲)
第七讲、指针(4讲)(核心)
第八讲、变量的作用域和存储方式(1讲)
第九讲、拓展数据类型(1讲)
第十讲、专题
字符串的处理(1讲)
进制转换(1讲)
补码(1讲)
动态内存分配(1讲)(重要)
综合应用:链表的使用(2讲)
ax^2+bx+c=0
写程序前先要建立思路
第一步:把一元二次方程的数据a,b,c三个系数保存在计算机里面
第二步:求出b^2-4ac的值(-b+-√b^2-4ac)/(2a)
大于零两个解,等于零一个解,小于零无解。
解题思路,将解题思路转化为计算机可以执行的语言
注:零基础看到代码会懵,这里省略代码步骤
个别序号可能会与原视频有所差异,内容基本无误
电影如何运行起来的:双击后,操作系统把电影在硬盘里的数据调用到内存条内,cpu去处理内存条内的数据,将一些数据发送给显卡,显卡将数据转化为图像通过显示器显示,将一些数据发送给声卡,声卡将数据转化为声音。
主板:主板上有很多插槽,其他的都插在主板上
通过编译和链接后生成一个后缀是.exe的可执行的文件,点击运行后,HolloWorld请求操作系统执行。操作系统调用cpu执行并通过显示器显示。
Win98、WinMe可以直接访问硬件(提供两个接口,可以通过操作系统访问硬件,也可以直接访问硬件)
其他的只提供一个接口,只能通过操作系统访问硬件
基本类型数据 分配多少字节由具体的C编译系统自行决定
整形: int 4字节
短整形: short int 2字节
长整形: long int 8字节
int i = 10,表示i变量是整形变量,i只能存放整数
int i = 10.6 //虽然10.6为小数,但因为数据类型为int型,所以仍为10
单精度浮点数 float 4字节
双精度浮点数 double 8字节
char 1字节 //并非任意一个字符就能识别,目前大多数系统采用ASCII字符集
结构体(用处不大,Java里已经没有了)
共用体(已淘汰)(作用:节省内存,但存在很多缺陷,相比能节省的内存,用处不大)
变量是一个字母,本质就是内存中一段存储空间。
把数据保存在计算机中是通过变量(容器)保存的。
#include
int main()
{
int i;
i = 3;
printf("i的值为:%d",i); //输出i的值
return 0;
}
3最终存放在内存中,程序终止之后3所占的空间被释放
写下int i后,会请求操作系统在内存(内存条)中找到一个空闲的单元,把单元与i产生关联。 i = 3是将3放在内存中与i有关联的单元中。
利用变量可以方便对数据的存储。
写完代码后,软件请求操作系统在内存条里分配一段空闲空间,然后把空间与字母i产生关联,以后使用i就是使用i对应的空间
初始化就是赋值的意思
#include
int main()
{
int i;
printf("i = %d\n",i);//\n为换行
return 0;
}
i没有初始化,输出值:-858993468
i和内存条中的空闲单元相关联后就输出,只定义了变量但没有赋值,所以输出的是垃圾值。(在visual studio里无法输出,显示错误:使用了未初始化的内存i,使用了未初始化的局部变量i)
内存条(硬件设备)里面只有0和1
1是高电频
内存条中的空闲单元使用完后把空间释放(并不是删除掉内容,而是使用权限可以分配给其他程序使用),所以不初始化变量,空闲单元内就会有以前程序使用过的垃圾值。但输出的值是固定的值叫做填充值:vc++发现没有给变量赋值,变量里面是垃圾值,就回自动将一个很大的值放在里面。
变量不初始化就没有实际意义
软件运行与内存关系(垃圾数据)
内存是在操作系统的统一管理下使用的!
1.软件在运行前需要向操作系统申请存储空间,在内存空闲空间足够时,操作系统将分配一段内存空间并将外存中软件拷贝一份存入该内存空间中,并启动该软件的运行!
2.在软件运行期间,该软件所占内存空间不再分配给其他软件
3.当软件运行完毕后,操作系统将回收该内存空间(注意:操作系统并不清空该内存空间中遗留下来的数据),以便再次分配给其他软件使用。
综上所述:一个软件所分配(使用系统分配表进行分配)的空间中极可能存在着以前其他软件使用过后的残留数据,这些数据被称之为垃圾数据。所以通常情况下我们为一个变量,为一个数组分配好存储空间之后都要对该内存空间初始化。
数据类型 变量名 = 要赋的值
等价于:
数据类型 变量名;
变量名 = 要赋的值;
举例子:
int i = 3;等价于:int i; i = 3;
int i,j; 等价于: int i; int j;
int i,j = 3 ;等价于: int i; int j; j = 3;
int i=3,j=5;等价于:int i; int j; i=3,j=5;
int i,j; i=j=5;等价于:int i,j; i=5; j=5;
进制就是逢几进一
N进制就是逢N进一
计算机只识别2进制
人类习惯用10进制
为了实际需要创造了八进制和十六进制
C语言规定八进制前要加0(注意是数字0,不是字母o),十六进制前要加0x或0X,十进制前什么都不加。
在汇编语言中:在数字后加字母B表示二进制数,加字母O表示八进制数,加字母D表示十进制数,加字母H表示十六进制数。
举例子:
1011B为二进制数1011,也记为(1011)2
1357O为二进制数1357,也记为(1357)8
2049D为十进制数2049,也记为(2049)10
3FB9H为十六进制数3FB9,也记为(3FB9)16
十进制
十个基数,逢十进一
0,1,2,3,4,5,6,7,8,9
二进制
两个基数,逢二进一
0,1
例如:0,1,10,11,100,101,110,111
计算机为二进制
计算机之父:冯诺依曼
将十进制改为二进制(二进制比较容易在硬件上实现,事物都有两种不同状态,如果分为十个不同状态太复杂了,一个硬件表示两个状态很容易,表示十个状态不容易)
十进制的5和二进制的101表示的是同一个数字(这个一定要理解)无论什么进制,都是数值的不同计算方式,本质上都是一样的。
计算机分五大部件:运算器,控制器,输入设备,输出设备,存储设备
人工智能之父:图灵
八进制
8个基数,逢8进一
基数:0,1,2,3,4,5,6,7
0,1,2,3,4,5,6,7,10,11
十六进制(字母大小写均可,注意出现时大小写统一即可)
16个基数,逢16进一
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
或
0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
单行注释://
多行注释:/**/
printf用法之输出控制符
%d表示以十进制输出
%c表示以字符型输出
% x或%X表示以十六进制输出
% o表示以八进制输出 字母o
#include 注:原视频中是以0x32C为例,因为不明显换成 0x32A
int main()
{
int i = 0x32A; //0x表示十六进制
printf("i = %x\n",i);//%x 小写x输出结果为32a
printf("i = %X\n",i);//%X 大写X输出结果为32A
return 0;
}
十进制:传统的写法
十六进制:在前面加0x或0X(数字零和x)
八进制:在前面加0(注意是数字零,不是字母o)
传统的写法: float x = 3.2;
科学记数法(一般都不用,但是遇到要认识):
float x = 3.2e3; //x的值是3200 正值小数点向右移
float x = 123.45e-2; //x的值是1.2345 负值小数点向左移
单个字符用单引号括起来
'A'表示字符A
'AB'错误
"AB"正确
字符串用双引号括起来
"A"正确,因为"A"代表了'A'和'\0'的组合
#include
int main()
{
float x = 123.45e-2;
//123.45e-2默认为double类型,把double赋给float会丢失进度,可以在123.45e-2后加个F
//123.45e-2F,表示将123.45e-2当做float来处理。
printf("%f\n",x);\n为换行
return 0;
}
整数是以补码的形式转化为二进制代码存储在计算机中的
实数是以IEEE754标准转化为二进制代码存储在计算机中的
字符的本质实际也是与整数的存储方式相同
1、代码的可读性强(可以让自己和别人更容易也更清楚的看懂程序)
很整齐,方便自己与他人看,不然时间久了就回变成垃圾代码,看着很乱。
工具软件,工程思想,注释占整个文档的1/3
2、降低代码出错的可能性,代码写规范,程序不容易出错
成对(永远先把成对的内容写完再写中间的内容,防止遗漏出错)
自动对齐(当想把{与上个语句对齐时,直接按{即可自动对齐)
缩进(地位相等不需要缩进,属于内部代码就需要缩进)
换行(代码的功能是相对独立的就需要换行)
一般程序可以分为三个部分:
定义变量
对变量进行操作
输出值
等号左右敲空格,if后面敲空格,运算级别最低的地方敲空格。
字节是存储数据的单位,并且是硬件所能访问的最小单位。
位(0或1)是最小的存储单位
1字节=8位 //位为bit(通常写为b),字节为Byte(通常写为B)
内存条中有许多小格子,一格一位(即一个0或一个1)但是cpu只能控制一个字节即8位。
cpu只能控制到字节,不能直接控制位,只有通过位运算符(软件)才能控制位
1字节 = 8位
1KB = 1024B //k→千
1MB = 1024KB //M→兆
1GB = 1024MB//G→吉
研究C和C++的必须要把这个问题搞清楚,学Java的不用
研究清楚就要学:补码
#include
int main()
{
int i = 45;
long j = 102345;
i = j; //将j的值赋给i,i由45变为102345
printf("i值=%d\nj值=%ld\n",i,j); //结果均为102345
float x = 6.6;
printf("x值=%f\n",x);
//结果为6.600000 float型小数有效数字为6位,不足6位输出时用0补全
int m = 2147483647; //结果为2147483647
printf("m值=%d\n",m);
int n = 2147483648;//结果为-2147483648
printf("n值=%d\n",n);
int k = 2147483649;//结果为-2147483647
printf("k值=%d\n",k);\n为换行
return 0;
}
变量i为整型占4个字节(int可以是16位也可以是32位)
整型能存放的最大值为2147483647(32位)
若将2147483648存放在变量n中,输出结果为-2147483648
若将2147483649存放在变量k中,输出得到-2147483647。依此类推
各数据类型所占用的存储单元长度由各编译系统自行决定,可使用sizeof进行查询
变量j为长整型占4个字节
若变量i可以把变量j的值装下,就不会丢失数据。
若变量i装不下变量j的值,就会丢失数据。
所以不同类型数据之间最好不要相互转化。
▶ char ch = 'A'; //正确
▶ char ch = 'AB';//错误,单引号只能括单个字符
▶ char ch = "AB"; //错误,AB是字符串,不能把字符串存放在单个字符变量中
▶ char ch = "A"; //错误,"A"是字符串"A\n",变量ch只能存放单个字符变量,不能存放字符串。
char ch = 'B';//此处错误,ch变量在上一行已经被定义了,这样会导致变量名被重复定义
char ch = 'A' 等价于
char ch;
ch = 'A';
#include
int main()
{
char ch = 'C';//正确
ch='D';
//ch是一个变量,可以多次赋值,但不可重复定义!
printf("%c\n",ch);//输出结果为D
return 0;
}
若字符变量在输出时不以%c输出而是%d输出
ch是一个二进制代码,可以用十进制形式表示出来,也就是将字符型转为整型
ASCII码不是一个值,而是一种规定。规定了不同字符是使用哪个整数值去表示。
'A' = 65 'B' = 66 依此类推
'a' = 97 'b' = 98 依此类推
'0' = 48
不同编码规定字母用不同的数字表示
例如:GB2312 UTF-8
#include
int main()
{
char ch1 = 'A';
printf("%c\n",ch1); //输出结果为A
char ch2 = 'A';
printf("%d\n",ch2);//输出结果为65
return 0;
}
字符本质上与整数的存储方式相同
基本的输入和输出函数的用法
第一种 printf("字符串");
#include
int main()
{
printf("哈哈哈!");
return 0;
}
第二种 printf("输出控制符" , 输出参数);
#include
int main()
{
int i=10;
printf("%o",i); //%o为输出八进制,结果为12
return 0;
}
第三种 printf("输出控制符1 输出控制符2 ....",输出参数1,输出参数2....);
输出控制符1和输出控制符2之间若无空格或其他字符进行分割,结果会挨在一起
输出控制符和输出参数的个数必须一一对应
#include
int main()
{
int i=10;
int m=20;
printf("%o,%d",i,m); //八进制输出变量i,整型输出变量m
//结果为 12,20 若无任何字符 结果为1220
return 0;
}
/*
建议将输出行改为:
printf("i=%o,m=%d",i,m);
结果为i=12,m=20 更加直观
*/
第四种 printf("输出控制符 非输出控制符",输出参数);
输出控制符:%d %ld %c %f %lf %o %x(或%x %X %#X ) %s(字符串)
非输出控制符 :\n
/*
编辑以下内容便于以后回顾时,利用注释中内容进行查找相应代码
某年某月某日
代码为了检验...
*/
#include
int main()
{
int x=47;
printf("%x\n",x);
printf("%X\n",x);
printf("%#x\n",x);//显示0x 推荐使用
printf("%#X\n",x);//显示0X 推荐使用
return 0;
}
/*
在某编译器中的输出结果为:
-------------------------
2f
2F
0x2f
0X2F
-------------------------
总结:.....
*/
-01组成的代码表示:数据也可以表示指令
-若01组成的代码表示的是数据的话,同样01代码的组合以不同的输出格式输出,会有不同的输出结果
通过键盘将数据输入到变量中
格式一:
scanf("输入控制符",输入函数);
将从键盘输入的字符转化输入控制符所规定格式的数据,存入以输入参数的值为地址的变量中
#include
int main()
{
int i;
scanf("%d",&i); //&i 表示i的地址 &为取地址符
printf("i=%d\n",i);
return 0;
}
/*---输入2,回车后显示的结果-----
i=2
-------------------------------*/
格式 二:
scanf("非输入控制符 输入控制符",输入参数);
将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中
注:非输入控制符必须原样输入
#include
int main()
{
int i;
scanf("m%d",&i);//输入m2为正确,只输2错误
printf("i=%d\n",i);
return 0;
}
/*---输入m2,回车后显示的结果-----
i=2
-------------------------------*/
例子: 一定自己试一下比较结果
#include
int main()
{
int i,j,k;
printf("请输入三个值,中间用空格隔开\n");
scanf("%d %d %d",&i,&j,&k);
//输入12 34,一直敲回车不会显示结果,直到输入第三个数,敲下回车
printf("i=%d,j=%d,k=%d\n",i,j,k);
return 0;
}
/*---输入12 34 56,回车显示的结果-----|改为"%d,%d,%d",回车显示的结果
请输入三个值,中间用空格隔开 |请输入三个值,中间用空格隔开
12 34 56 |12 34 56
i=12,j=34,k=56 |i=12,j=0,k=0
---相同数字输入后回车显示的结果----- |改为"%d,%d,%d",回车显示的结果
请输入三个值,中间用空格隔开 |请输入三个值,中间用空格隔开
12 |12
34 |i=12,j=0,k=0
56 |敲回车后直接输出,34 56无法键入
i=12,j=34,k=56 |
-------------------------------*/
- 使用前建议先用printf提示用户以什么样的方式来输入
- scanf中尽量不要使用费事如控制符,尤其是\n
#include
int main()
{
int i,j,k;
printf("请输入三个值,中间用空格隔开\n");
scanf("%d %d %d\n",&i,&j,&k);
//输入12 34,一直敲回车不会显示结果,直到输入第三个数,敲下回车
printf("i=%d,j=%d,k=%d\n",i,j,k);
return 0;
}
/*---输入12 34 56,回车显示的结果---中间输入的回车无法输出,输入\n后才可显示结果
请输入三个值,中间用空格隔开
12 34 56
\n
i=12,j=34,k=56
-------------------------------*/
例子:未修改前
#include
int main()
{
int i;
scanf("%d",&i);
printf("i=%d\n",i);
//................若干行代码
int j;
scanf("%d",&j);
printf("j=%d\n",j);
return 0;
}
/*---输入12后不小心输入m,回车后显示的结果---
12m
i=12
j=0
-------------------------------*/
//注:j的值编译器不同结果也不同,郝斌老师编译器输出结果为-858993460
例子:修改后 暂时不用管具体如何实现
#include
int main()
{
int i;
char ch;
scanf("%d",&i);
printf("i=%d\n",i);
//................若干行代码
while((ch=getchar())!='\n') //循环语句
continue;
int j;
scanf("%d",&j);
printf("j=%d\n",j);
return 0;
}
/*---输入12后不小心输入m,回车后再次输入数值显示的结果---
12m
i=12
22
j=22
-------------------------------*/
//若显示i的值后,不输入值,一直敲回车也不会显示j的值
算数运算符
+ - * / %
加 减 乘 除 取余
关系运算符
> >= < <= != ==
不等于 等于
逻辑运算符
! && ||
非 与 或
赋值运算符
= += *= /= -=
优先级别
算数>关系>逻辑>赋值
例子:int k=3+2*4&&5||6-4+=6
可直接在编辑时,加上()
▶除法
被除数/除数 == 商
被除数和除数均为int,商为int
int / int == int
5/3==1 3/5==0 -5/3 == -1 -5/-3 == 1
被除数和除数中有一个为float,商为float,不截取小数部分
int / float == float 16/5.0==3.20000
float / int == float 16.0/5==3.20000
典型例题为:s=1+1/2+1/3+1/4+....+1/100的值 具体程序学到循环结构的时候讲
▶取模 取余
运算对象必须是整数,取余的结果是整除后的余数
注意:最终结果的符号与被除数相同
13%3 == 1 13%-3 == -1 -13%3 == -1 3%5 == 3
测试取模的例子
#include
int main()
{
printf("%d %d %d %d %d %d\n",3%3,13%-3,-13%3,-13%-3,-13%23,3%5);
return 0;
}
/*-----------输出结果-----------
0 1 -1 -1 -13 3
-------------------------------*/
如果实在绕不过弯来,可以参考一下我的笨方法 (勿喷,用画图工具临时画的)
5/3=1 5%3=2 3/5=0 3%5=3 小%大=小
! && ||
非 与 或
!真 → 假
!假 → 真
&& 有一个假则为假,两个真才为真
&&左边的表达式为假,右边表达式肯定不会执行
真&&真 → 真
真&&假 → 假
假&&真 → 假
假&&假 → 假
|| 有一个真则为真,两个假才为假
||左边的表达式为真,右边表达式肯定不会执行
真||真 → 真
真||假 → 真
假||真 → 真
假||假 → 假
C语言对真假的处理
零是假 非零是真
例子一:
#include
int main()
{
int i=10;
int k=20;
int m;
m=(3>2)&&(k==8); //3>2为真 20==8为假 真&&假为假 假为0
printf("m=%d,k=%d\n",m,k);
return 0;
}
/*-----------输出结果-----------
m=0,k=20
-------------------------------*/
例子二:
#include
int main()
{
int i=10;
int k=20;
int m;
m=(1>2)&&(k==5); //1>2为假,不再向下运行,k==5不执行
// m=(1>2)&&(k==5) 不含分号是表达式,含分号的是语句
printf("m=%d,k=%d\n",m,k);
return 0;
}
/*-----------输出结果-----------
m=0,k=20
-------------------------------*/
例子三:
#include
int main()
{
int i;
char ch;
scanf("%d",&i);
printf("i=%d\n",i);
scanf("%c",&ch); //ch为字符,1字节
printf("ch=%c\n",ch);
return 0;
}
/*----输入92845nm,输出结果-----------
92845nm
i=92845
ch=n
-------------------------------*/