一、C语言的关键字(32个)
1.类型相关的:
char,double,float,int,long,short,signed,struct,union,unsigned,void,enum
2.存储相关的:
auto,const,extern,register,static
3.结构相关的:
break,case,continue,default,do,else,f,while,for,goto,return,switch
4.特殊功能:
sizeof,typedef,volatile
二、计算机中的数据表示
1.数值数据:10、3.5......即一个数。
2.非数值型数据:自然语言。
3.C语言中使用""引用其他的数据称为字符串。
4.数据存储与表示:
计算机只能处理与存储0和1类型数据,最小单位是bit,内存最小单位是字节,1Byte=8bit。
5.进制的表示:0b:二进制,没有前缀默认为十进制
0o:八进制
0x:十六进制
数据类型:即对不同类型的数的表示和存储。
char:字符型 8bit 1字节
short:半字类型 16bit 2字节
int:整型 32bit 4字节
long:长整型 64bit 8字节
signed:有符号类型
unsigned:无符号类型
signed char:有符号字符型
unsigned char:无符号字符型
C语言是强类型语言,任何变量或存储空间必须要先定义(给定类型),然后才能使用且使用过程中类型不能更改。
浮点数存储:
float:单精度浮点型,有效十进制位数约6位,4字节存储
double:双精度浮点型,有效十进制位数约15位,8字节存储
逻辑上:布尔类型:
bool: 真或假,C语言中非0为真,0为假
void:空类型
C语言中的常量:
常量:程序运行过程中始终不变的量
整型常量: 5 10 -5 整数值 8
浮点常量: 2.5 -3.7
指数常量: 3.0e-26 => 3*10^-26
字符常量: 单个英文字符 'a' '8' === 56 ASCII
字符串常量: 多个字符放在一起 "hello world"
在内存中 存储的是 字符的 编码 连续存储
标识常量(宏定义):本质上是给常量定义一个字符串形成的别名,格式:#define 宏名 值
变量:程序运行过程中可能改变的量,其本质即给一个内存空间命名,通过该名字访问内存。
C语言中的变量:1.先定义再使用;2.定义时给定类型,一旦定义完成,其类型将不能改变。
变量的定义:存储类型 数据类型 变量名;
变量名:由编程者自己定义的名字
程序中变量名、函数名、宏名都是标识符
命名规范:1.只能由字母、数字、下划线组成,区分大小写;2.不能由数字开头;3.不能与关键字重名
存储类型:决定了变量存储的位置
C语言内存结构:
1.代码段:存储代码,即编译的二进制指令(只读)
2.常量区:存储程序中的常量、字符串的部分(只读)(可以使用const关键字修饰全局变量,将该变量的位置变更为常量区)
3.静态区:可读可写,只能被初始化一次,在程序开始运行时
4.堆区:由程序员在程序运行时可以动态申请或释放的内存
5.栈区:有程序运行时自动申请或释放的内存
6.系统区:LinuxC有,存储操作系统对于该进程的一些数据进程控制块,内存占用情况,环境变量等由系统维护的数据(只读)
全局变量:变量定义的位置在函数外(不在任何函数内{})
局部变量:变量定义的位置在函数内
auto修饰全局变量,该变量存储于静态区
auto修饰局部变量,该变量存储于栈区
const修饰全局变量,该变量存储于常量区
static修饰局部变量,该变量存储于静态区
static修饰全局变量,该变量存储于静态区
static修饰函数,该函数只能在本文件内使用
extern修饰全局变量,表示外部引入存储类型,不开辟新的空间,是一种声明
extern函数:表示引入外部文件实现的函数
register:寄存器类型声明,表示变量尽量使用寄存器存储,通常用于存储在一段代码中使用极其频繁的量,该存储类型的变量不能取地址。
数据类型的转换:
1.隐式类型转换:由编译器自动完成一些默认转换模式
2.强制类型转换:编程者手动进行的强制性的类型转换,变量或值前使用(目标类型)
类型的转换过程:
float转换为int:舍弃小数,取整操作
int转换为float:整型(精确类型),小数(非精确类型),精度会丢失
int转换为char:溢出部分舍弃,宽存储空间转换为小存储空间
int转换为short:小存储空间转换为宽存储空间不影响
整型与浮点型参与运算时,隐式类型转换会统一转换为浮点型运算。
有符号数,无符号数强制类型转换时,存储内容完全没有改变影响计算。
C语言中的标准输入与输出:
标准输入:程序终端输入的内容;
标准输出:程序输出到终端显示
输出:
putc():输出一个字符
putchar():与putc一样
puts():输出一个字符串
printf():格式化输出函数
使用: format 格式控制字符串 "a=%d\n",a 其中 a=\n 原样输出
%d 格式占位控制符
%d:输出整型有符号数,以十进制方式显示
%x:输出整型无符号数,以十六进制方式显示
%u:输出整型无符号数
%c:输出一个字符型,以字符方式显示
%s:输出一个字符串,以\0作为结束符
%%:输出%本身
%f:输出一个浮点类型,以十进制方式
附加格式说明符(修饰符):
%8d 输出整型有符号数 以10进制方式显示
在数据值宽度低于8个字符位置时 填充空格维持8个字符位置
-8 向左对齐
8 默认右对齐
%.2f 输出一个浮点类型 以10进制方式 保留2位小数 四舍五入
%ld 输出整型有符号数 宽度为8字节long 以10进制方式显示
%lf 输出 double 类型的浮点数
标准输入:
getchar():得到一个字符
char * fgets(char*s,int size,FILE*stream);(s:存放输入字符串的容器;size:容器的大小,单位字节;stream:stdin)
scanf:格式化输入
格式控制字符串: 非常类似于printf
%d 表示 输入提取为一个整型数
%f 表示 输入提取为一个小数数
%4d 表示 输入提取为一个整型数 宽度为4个数字
%4c 表示 输入提取4个字符 组成字符串
%s 输入一个字符串 默认以空格 或 回车 或 制表符(tabl)
scanf处理输入字符串时会存在输入残留,通常会导致残留到下一次输入内容
处理残留:
方法一:
%*c:将后续所有字符都取出丢弃
%*6d:取出6个数字丢弃
%*2c:取出2个字符丢弃
方法二:
scanf结束后使用fgets将后续残留都读取出来
运算符: 代指某种操作的 符号
表达式: 由 运算符 与 数据 按某种顺序 组合而成的 可以计算的一个 式子
C语言中 可以支持的运算符有:
1.算数运算符: +加 -减 *乘 /除 %求余 求模
/除 5 / 3 == 1 整数除法是求商 浮点数除法 结果为浮点数
%求余 必须是整数 5 % 3 == 2
其他数学运算 没有对应运算符 可以通过math库 实现
双目运算: 需要两个数参与的运算符
2.逻辑运算: 真 与 假的 运算
符号
逻辑与 && 双目运算 真 && 真 结果为真 一假得假
逻辑或 || 双目运算 假 || 假 结果为假 一真得真
逻辑非 ! 单目运算 !真 == 假
非0 为真 0假
5 || 0 结果 真 1
5 && 0 结果 假 0
!0.5
3.关系运算 大小比较 结果 真或假
> < == != >= <=
4.位运算 计算机中特有的运算 所有运算目标 均针对二进制而言
按位 & 将二进制中的每一位进行与操作 与0得0 与1不变
按位 | 将二进制中的每一位进行或操作 或1得1 或0不变
按位取反 ~ 单目运算
按位异或 ^ 相同为0 不同为1
移位运算
逻辑左移 << 高位移出丢弃 低位补0
算数右移 >> 低位移出对齐 无符号数 高位补0 有符号数 高位补符号位
选择运算 三目运算符:
a ? b : c;
逻辑: 若a 为真 则 执行 b; 表达式的值 为 b
若a 为假 则 执行 c; 表达式的值 为 c
逗号运算符,
表达式1, 表达式2, ... 表达式n;
运算逻辑, 每个表达式都执行一下, 整个表达式的值 为 表达式n 的值
a = 5, b = 10;
z = (x+=5, y = x+0.2);
&变量名 取地址符 得到变量的内存首地址 只能对变量或有内存空间的量使用
sizeof运算符: sizeof(变量名或类型名); 用于计算变量或类型 占用的内存空间大小 单位字节
自增自减运算符 ++ -- 单目运算
前缀++ 运算符 ++a; 先+ a=a+1 后用
后缀++ 运算符 a++; 先用 后+ a=a+1 指a++表达式结束
前缀-- 运算符 --a; 先- a=a-1 后用
后缀-- 运算符 a--; 先用 后- a=a-1
优先级问题:
1. 优先级提升运算符 ()
2. 单目运算符 优先级高 ++ -- & + - ! ~
3. 算数运算符 高于 移位运算 高于 关系运算 高于 位运算 高于 逻辑运算
4. 吊车尾 3兄弟 三目运算 赋值运算 逗号运算符
C语言中的结构性语句:
1.顺序结构
2.分支结构 需要根据条件选择性执行某些代码或跳出某些代码
二分支:
if(条件表达式)
{
语句块1;//当条件表达式的值为真时,语句块1执行else
}
else
{
语句块2;//当条件表达式的值为假时语句块2执行
}
格式简化或变种:
1.语句块只有一行C代码,即只有一个;结束,代码块的{}可以省略
2.else部分没有代码,else{}都可以省略。
if嵌套:即if的代码块中包含if结构
多分支:
switch(整型表达式)
{
case 常量整型表达式1:语句块1;break;
case 常量整型表达式2:语句块2;break;
......
default:语句块n;
}
(整型表达式:表达式的值是一个整数;常量整型表达式:表达式的值是一个整数,不能有变量)
运算逻辑:计算整型表达式的值,依次从上到下与case中的常量整型表达式的值,若相等,则执行对应case后的语句块,若遇到break关键字,退出switch,若没有break关键字,继续向下执行后续case中的语句块;若不相等,则继续向下比较其他case中的值。
default语句块在没有命中case中的值时执行该语句块,若一直没有brake关键字,也会执行到default语句块。
使用色:1.switch结构只对整型结构有效;2.不能对变量进行case;3.case中的值不能存在相等的
3.循环结构:根据条件对某些代码重复执行
通常在程序中需要反复执行某些动作,则需要循环,即在某些情况下,程序会跳转到前面去继续执行代码 。
while循环结构:
while(条件表达式)
{
循环语句块
}
执行逻辑:1.先判断条件表达式的真假,若真,执行一次循环语句块再回到动作1,若假,退出循环,即循环结束了。
do while循环
do{
循环语句块;
}while(条件表达式);
执行逻辑:1.先执行一次循环语句块;2.再判断条件表达式的真假,若真,执行一次循环语句块,再回到动作2,若假,退出循环,即循环结束。
for循环
for(循环初始化语句;循环条件表达式;递进表达式)
{
循环体;
}
执行逻辑:1.先执行一次循环初始化语句;2.判断循环条件表达式的真假,若真,执行循环体一次,再执行一次递进表达式回到动作2,若假退出循环
递进表达式: 即使continue提前结束了本次循环,下一次循环开始前递进表达式也要执行
缩略写法:
若循环初始化语句没有可以不写
若循环条件表达式不写表示一直为真
若递进表达式不需要 也可以省略不写
死循环:
for(;;)
{}
while(1)
{}
循环控制关键字:
1.break:提前跳出循环,不执行循环了,对与嵌套循环,只能跳出本循环
2.continue:继续提前结束本次循环,重新开始下一次循环
3.goto:程序跳转关键字只能在同一个函数中进行跳转
构造数据类型: 有程序员设计的数据类型 ,基于基本数据类型的组合
数组:将多个相同类型的数据连续、有序存放构成的数据类型;
数组的元素:即数组中的每一个数据
数组定义:存储类型 元素数据类型 数组名[元素个数]
数组的初始化: 定义数组时给定 初始值
int arr[5] = {初始化表};
int arr[5] = {1,2,3,4,5};
int arr[5] = {1,0,2}; //初始化表 没有包含全部元素, 剩余元素默认赋值为0
int arr[] = {1,2,3,4}; //定义数组时, 没有给定元素个数,但有初始化表
//则 数组的个数将由 初始化表中元素个数决定
int arr[]; // 不能这样定义 , 编译器无法确定你元素的个数
int arr[5] = {0}; //将数组元素全部初始化为0
int arr[5];
数组定义时 元素个数 必须预先已知和确定
即 定义数组时 其元素个数不能是变量
即 程序运行起来前, 数组元素个数应该已经确定
数组的使用:
元素访问: 读 写 数组中的元素
使用 [] 元素访问运算符
例如:数组名[元素下标]
元素下标:数组中元素从0开始自左向右依次编号,元素下标可以是整型表达式。
数组的遍历:即将数组中的每一个元素访问一次
除初始化外,数组不能通过元素列表方式赋值
数组名:1.代指这个数组本身;2.代指这片内存空间的首地址
数组的内存模型:数组占用空间为元素个数*每个元素的长度
&arr[0]:该表达式表示取数组中的0号元素的地址
字符串:本质也是一个数组,char类型的数组
char buf[20];
fgtes(buf, sizeof(buf), stdin);
常量字符 "hello"
代指 1. 这个字符串本身 char buf[20] = "hello";
2. 代指 常量字符串 在常量区的地址
字符串的长度:从字符串开始到结束'\0'值中间有多少个字符
二维数组: 即数组中的元素 是一个数组(一维数组)
实例:二维数组定义:int arr[2][3]
初始化:int arr[2][3] = {{88,79,99},{78,100,60}};
二维数组的存储模型, 数组的访问模型;
二维数组在逻辑上可以表示行列平面模型
在存储上 按行列展平存储
二维字符数组:
在一个数组中存多个字符串
函数:
完成特定功能的代码块的集合
函数的输入和输出:
输入:终端输入 参数输入 硬件输入,可以没有输入
输出:终端输出 返回值输出 硬件输出 其他的逻辑输出,任何函数都有输出
1.定义函数
返回值类型 函数名(参数列表)
{
函数体;
}
返回值类型:一个函数可以有返回值,也可以没有 void修饰
int float char 返回值可以在4或8字节
通常返回值:1.表示函数执行成功或不成功的标志
2.返回一些简单的结果
函数名:标识符,有编程者自己定义,通常根据其功能命名
(参数列表):用于调用函数时传递给函数的一些参数,也可以没有参数void修饰或不写
():可能有参数,但用不到;
(void):肯定没有参数
一个函数的参数可能不止一个,多个参数用逗号隔开
函数体:该函数功能实现的逻辑代码
函数需要调用才能得以执行,什么时候调用由调用者决定
函数的意义:
1.对功能代码的封装,方便于多文件开发
2.提高代码的复用性
函数名(实参列表)
实参列表应该与形参列表一一对应,不能多也不能少,参数类型要一致
函数原型:除了函数体外的部分称函数原型
函数声明:即在函数调用前声明一下该函数,将该函数的原型写到调用前