计算机的基本构成
输入(键盘)输出设备(鼠标)
CPU处理器、存储器、程序
存储器分为内存和外存
内存:工作存储器,容量小速度快
外存:容量大速度慢
存器:CPU内部存储器,速度快容量小
什么是程序
计算机能够识别的一组有序的指令叫程序
指令是计算机能够识别的操作
例如a.out
程序的设计步骤
Vim(编辑)->gcc(编译)->./a.out(运行/调试);
计算机的数据表示
非数值数据:字符图片声音
数值数据:可以直接进行运算的数据,如二进制、0八进制、十进制、0x十六进制等,进制间可以相互转换
十进制转其他进制:
转二:除2倒取余
转八:除8倒取余
转十六:除16倒取余
二进制和八进制421
二进制和十六进制8421
基本数据类型
关键字:系统预定义好,有特殊含义的,都是小写,不能重新定义
共有32个:
数据类型:char short int long float double enum union struct void
控制语句:if else for do while switch case dafault break continue goto
存储类型:auto static extern register
Const:只读
Sizeof:计算所占内存空间的大小,单位:字节
Typedef:给一个已有的数据类型起别名
volatile:防止编译器优化
标识符:程序员自己定义,一般用来定义变量名,函数名,类型名
有符号数和无符号数
有符号数有正数有负数,所有数据都以补码的形式保存在计算机中
原码:直接转为二进制,并且最高位表示数据位
反码:符号位不变,其他位取反
补码的补码就是原码
无符号数只有正数,并且都是数据位
字符型家族
值域范围:
char->0-255
Signed char ->-128~127
浮点型家族
Float(单精度浮点数):表示6~7位有效数据
%f默认输出小数点后6位
双精度浮点数(双精度浮点数):表示15~16位有效数据
%lf默认输出小数点后6位
要输出小数点后n位%.nf
常量
在运行期间不会不能被改变的量
字符常量:’a’’b’’c’
整型常量:二进制,八进制,十进制等
浮点型常量:小数,指数
%g:选择小数或者指数比较短的形式进行输出
字符串常量:以’\0’结尾
标识常量(宏):#define 宏名 表达式
宏只是单纯的替换,必须大写
宏函数:
#define 函数名(形参) 函数体
变量
定义:意味着要在内存空间中开辟空间
定义一个变量:存储类型 数据类型 变量名
存储类型:决定开辟的空间在内存中的哪个区域
数据类型:决定了开辟的空间的大小
变量名:开辟的内存空间的名字
局部变量:定义在函数体内的变量
全局变量:定义在函数体外的变量
存储类型
Auto static extern register
Auto:修饰局部,修饰的变量存储在栈区
Static:全局和局部变量都可以修饰,修饰的变量存储在静态区
extern:修饰全局变量,修饰的变量存储在静态区
Register:修饰局部变量,存储在寄存器
初始化:在定义变量的时候进行赋值
Int a = 10;
static:修饰局部变量时,延长了局部变量的生命周期|修饰全局变量时,限制了作用域
生命周期:从开辟空间到释放空间
作用域:使用的范围
数据类型转化
强制类型转换
Flaot a=3.14;
Int b=0;
b=(int)a;
隐式类型转换
Char,short->int ->unsigned ->long ->double <-float
运算符
算术运算符
加减乘除 + - * / % ++ --
%:取余
只能用于整数
++在前先自加再赋值
++在后先赋值再自加
单独成立一条语句就都相当于给a+1
关系运算符
比较两者之间的关系,真1假0(> < >= <= == !=)
常量写在等号的左边
逻辑运算符
&& || !
&&:表达式1 && 表达式2
截断法则:前一个为假,结果为假
||:表达式1 || 表达式2
截断法则:有一个为真,结果就为真
Sizeof运算符
Sizeof(数据类型)
Sizeof(变量名)
三目运算符
表达式1 ? 表达式2 : 表达式3
判断表达式1是否成立,成立就将表达式2的值作为整个表达式的值,否则就将表达式3的值作为整个表达式的值
逗号运算符
表达式1,表达式2,表达式n
从左往右依次执行,最后将表达式n的值作为整个表达式的值,使用时加上括号
位运算符
& | ~ ^ << >>
输入输出
函数:有独立功能的模块
输入:将键盘输入数据拷贝到内存中
输出:将内存数据打印至终端
输出
Printf(“格式控制串”,输出表);
格式控制串:原样输出的内容
输出表:输出的内容
整型
%d:以十进制进行输出
%o:以八进制进行输出
%x:以十六进制进行输出
#:自动再八进制和十六进制前加上前缀
%hd:short类型
%ld:long类型
%lld:long long类型
%c:字符型
浮点型
%f:float
%lf:double
%e:以指数形式进行打印
%g:选择小数和指数中较短的进行输出
输入
Scanf(“格式控制串”,地址表);
格式控制串:原样输出的内容+格式化符
&变量名
%*c:抑制符
字符的输入输出
输入
Getchar(),返回值:获取到的ascii码值
输出
Putchar()
需要的参数:字符的ascii码值
三大结构
顺序结构
语句按照一定的顺序去执行
选择结构
单分支if选择结构
If(表达式)
{
语句;
}
判断表达式是否成立,成立就执行语句
双分支if选择结构
If(表达式)
{
语句1;
}
else
{
语句2;
}
先判断表达式是否成立,如果成立,则执行语句1,否则,执行语句2
多分支选择if结构
If(表达式1)
{
语句1;
}
}
Else if(表达式n)
{
语句n;
}
Else
{
语句n+1;
}
从上往下,依次去判断表达式是否成立,如果表达式成立,则执行对应的语句
案例:输入成绩,判断成绩的等级
switch语句
Switch(表达式)
{
Case 标号1:
语句1;
Case 标号2:
语句2;
Case 标号3:
语句3;
。。。。
Case 标号n:
语句n;
default:
语句n+1;
}
表达式不能为float类型,标号为常量,当表达式等于标号时,就冒号后面的语句,直到switch case语句结束
或者遇到break语句结束
循环结构
for循环
for(表达式1;表达式2;表达式3)
{
循环体;
}
表达式1:循环的起始条件
表达式2:循环的终止条件
表达式3:循环变量的变化
先执行表达式1,然后执行表达式2,如果表达式2为真,执行循环体,然后执行表达式3;如此反复,当表达式2为假时,结束循环
while语句
While(表达式)
{
循环体;
}
判断表达式是否成立,如果成立,就执行循环体,反之,跳出循环
Do while语句
do
{
循环体;
}while(表达式);
先去执行循环体,然后判断表达式是否成立,如果成立,就继续去执行循环体内的语句,否则,结束循环
break:1、结束switch,case语句 2、跳出循环(结束循环)
continue:跳出循环(跳出本次循环,进入下一次循环)
死循环
while(1)
{
循环体
}
2、
for( ; 1 ; )
{
循环体
goto:无条件跳转语句
goto 标号:
数组
一组数据类型相同的元素组合在一起
特点,类型相同,地址连续
存储类型 数据类型 数组名[元素的个数]
数据类型:去掉变量名剩下的就是数据类型
访问
数组名[下标] 下标从0开始
冒泡排序
从左往右,两两依次比较,如果前一个数比后一个数大,就交换位置,反之,不变
字符数组
整型数组:保存一组int类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
Int arr[5];
字符数组:保存一组char类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
定义: char str[10];//定义了一个字符数组str,该数组中可以存放10个char类型的字符
数组所占的内存空间== sizeof(char)*10 = 10
数组的数据类型:char [10];//去掉数组名
字符数组的本质就是字符串
输出函数
%s:字符串
Printf(“%s”,str)
Puts(数组名)
功能:将数组的内容打印到终端,并自动换行,打印到’\0’结束
输入函数
Scanf(“%s”,str)
Gets(数组名)
功能:将输入的字符串保存在数组中,并在末尾添加’\0’
Scanf写在gets之上时,会出现异常情况(gets吃掉了‘\n’)
- gets以回车作为结束符,但是scanf以空格,回车TAB作为变量输入结束的标志
2、
缓冲区:
Gets在输入结束后,会自动清空缓冲区的内容
Scanf在输入结束后,会在缓冲区中遗留空格、回车、tab
输入:
Gets:进行输入时,回先去检查缓冲区的内容,如果缓冲区有内容,会率先输出缓冲区当中的内容
Scanf:键入,不会检查缓冲区的内容
puts会自动换行,而printf不会
求字符串的长度
Strlen(数组名)
功能:求字符串的长度
返回值:求得的字符串的实际长度,不包含’\0’
strlen和sizeof的区别:
- strlen求到的是字符串的实际长度,而sizeof求到的是申请到的内存空间的大小
- Strlen是一个函数,sizeof是一个运算符
字符串的拷贝函数
Strcpy(数组1,数组2/字符串);
作用:将数组2中的内容拷贝给数组1,包含‘\0’,相当于完全拷贝
Strncpy(数组1,,数组2/字符串,n);
作用:将数组2或者字符串中的前n个字符拷贝给数组1
字符串的链接函数
Strcat(数组1,数组2/字符串);
功能:将数组2中的内容连接到数组1中去,数组1中的’\0’会被覆盖
Strncat(数组1,数组2/字符串,n)
功能:将字符串2的前n个字符连接到字符串1后
比较函数
Strcmp(数组1/字符串1,数组2/字符串2);
功能:比较字符串1和字符串2的大小
返回值:
大于0:字符串1 > 字符串2
等于0:字符串1 == 字符串2
小于0:字符串1 < 字符串2
比较规则:从左往右,依次去比较字符串中的每个字符的ascii值,直到遇到不同的ascii码或者遇到‘\0’,结束比较
二维数组
二维数组:(数组数组):一堆数组的元素组合在一起
存储类型 数据类型 数组名[行数][列数]
行数:一维整型数组的个数
列数:一维整型数组中元素的个数
函数
为了提高代码的复用率使用函数
库函数:printf scanf strlen
引入头文件
#include <stdio.h>
#include <string.h>
调用函数
函数名(参数);
Strlen(参数);
返回值:int(字符串的实际长度)
函数名(实际参数列表)
函数声明:如果函数没有写在main函数前就需要声明,将函数头部直接复制粘贴在main函数前,加上分号
声明的作用是帮编译器做语法检查
指针
指针是一种保存地址的数据类型
地址的本质是指针,每一个字节都有编号,这个编号就叫做地址
存储类型 数据类型 * 指针变量名
指针的赋值相当于改变指针的指向
二级指针
用来保存一级指针的叫二级指针
指针的算数运算
p+n:p向地址增大的方向移动了n个数据
p实际的变化:p + sizeof(指针指向的数据类型)*n
P-n: p向地址见效的方向移动了n个数据
p实际的变化:p - sizeof(指针指向的数据类型)*n
P++: p向地址增大的方向移动了一个数据 //改变指针的指向
p = p+sizeof(指针指向的数据类型)
P--:p向地址减小的方向移动了一个数据 //改变指针的指向
p = p-sizeof(指针指向的数据类型)
p-q:(p和q数据类型必须相同):这两个指针之间相隔的个数
实际的变化:(q-p)/sizeof(指针指向的数据类型)
数组名和指针变量的区别:数组名是指针常量,指针常量不能自加自减
数组指针和指针数组
数组指针:指向数组的指针
存储类型 数据类型 (* 变量名) [元素的个数];
指针数组:元素为指针的数组
存储类型 数据类型 * 变量名[元素的个数];
数组中元素的数据类型是int *
const修饰
const进行修饰时,不能直接修改变量的值,但是可以通过指针,间接修改a的值
const在*的左边时:*p不能被改变;(值)
Const在*的右边时: p 不能被改变;(指向)
main函数传参
表示字符串的个数
Int argc;
保存你传入的每一个字符串的地址
Char * argv[ ];
Int main(int argc, char * argv[])