C语言学习笔记 【未完待续】
文章目录
数据类型
-
整数 占用字节
整型 --int --4
短整型 --short int --2
长整型 --long int --8 -
浮点数【实数】
单精度浮点数 --float --4
双精度浮点数 --double --8 -
字符
单个字符 --char --1
复合数据类型
-
结构体
-
枚举
-
共用体
-
强制类型转换
格式:
(数据类型)(表达式)功能:
把表达式的值强制转化为前面执行的数据类型例子:
(int)(4.5+2.2) 最终值是 6
(float)(5) 最终值是 5.0000000
变量
本质就是内存的中的一段存储空间
-
变量为什么必须初始化;所谓初始化就是赋值的意思
-
如何定义变量
数据类型 变量名 = 要赋的值;
等价于
数据类型 变量名 ;
变量名 = 要赋的值;
例如:
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;
什么是进制 ---- 逢几进一
十进制 --逢十进一 基数:0123456789
二进制 --逢二进一 基数:01
八进制 --逢八进一 基数:1234567
十六进制 --逢十六进一 基数:123456789ABCDEF
C语言规定八进制前要加0(是0不是字母o),十六进制前要加0x或0X,十进制前什么都不加!
在汇编中:在数字后面加字母B表示二进制,加字母O表示八进制,加字母D表示十进制,加字母H表示十六进制。
常量在C语言中如何表示
整数:
十进制:传统的写法
十六进制:前面加字母0x或0X
八进制:前面加0(零)
浮点数:
传统写法:
float x = 3.2;//传统
科学计数法:
float x = 3.2e3;//x的值是3200
float x = 123.45e-2;//x的值是1.2345
浮点数存储所带来的问题
float 和 double 都不能保证可以精确的存储一个小数
举例:(存储的是相似值)
有一个浮点型变量x,如何判断x的值是否是零
if (|x-0.000001| <= 0.000001)
是零
else
不是零
循环更新的变量不能定义成浮点型
字符:
单个字符用单引号括起来 ‘A’表示字符A ‘AB’错误–"AB"正确
字符串用双引号括起来 "A"正确,因为"A"代表了’A’’\0’的组合
常量以什么样的二进制代码存储在计算机中
整数是以补码的形式转化为二进制代码存储在计算机中的
实数是以IEEE754标准转化为二进制代码存储在计算中的
字符的本质实际上也是与整数的存储方式相同
代码规范化 推荐书籍《高质量C/C++编程》–林锐
代码可读性更强 书写更不容易出错
什么是字节
字节就是存储数据的单位,并且是硬盘所能访问的最小单位
1字节 = 8位
1K = 1024字节
1M = 1024K
1G = 1024M
不同数据之间相互赋值的问题
暂不考虑
int i = 45;
long j = 102345;
i = j;
printf("%ld %d\n", i , j);
float x = 6.6;
double y = 8.8;
printf("%f %lf\n,x, y");
什么是ASCII
ASCII不是一个值,而是一种规定,
ASCII规定了不同的字符是使用哪个整数值去表示。
它规定了
'A'--65 'B'--66 'a'--97 'b'--98 'O(零)'--48 'O(字母)'--79
字符的存储【本质上与整数的存储方式相同】
基本的输入和输出函数的用法
四种用法
-
printf(“字符串\n”);
-
printf(“输出控制符”,输出参数);
-
printf(“输出控制符1 输出控制符2 …”,输出参数1,输出参数2…);
-
printf(“输出控制符 非输出控制符”,输出参数);
输出控制符:
printf()–
输出控制符和输出参数的个数必须一一对应
%d – int(整形)
%ld – long int
%c – char
%f – float(浮点数)
%lf – double
%x(或者%X或者%#X) – int 或 long int 或 short int
%o – 同上
%s – 字符串
为什么需要输出控制符
- 01组成的代码可以表示数据也可以表示命令
- 如果01组成的代码表示的十数据的话;那么同样的01代码组合以不同的输出格式输出就会有不同的输出结果
输入控制符
scanf()【通过键盘将数据输入到变量中】
两种用法:
用法一:scanf(“输入控制符”,输入参数);
功能:将从键盘输入的字符转化为输入控制符所规定的数据,然后存入以输入参数的值为地址变量中
用法二:scanf(“非输入控制符 输入控制符”,输入参数);
功能:将从键盘输入的字符转化为输入控制符所规定的数据,然后存入以输入参数的值为地址变量中
非输入控制符必须原样输入
如何使用scanf编写出高质量代码
1.使用scanf之前最好先使用printf提示用户以什么样的方式输入
2.scanf中尽量不要使用非输入控制符,尤其不要用\n
scanf(" %c");前面必须加一个空格!(原因请查阅书籍:C Primer Plus)(空白符问题)
3.应该编写代码对用户的非法输入做适当的处理【非重点】
char ch;
while((ch=getchar())!='\n')
continue;
运算符
算术运算符
+ - *(乘) /(除) &(取余数)
关系运算符
> >=(大于等于) < <=(小于等于) !=(不等于) ==(等于)
逻辑运算符
!(非) &&(并且) ||(或) &(取地址)
!真 假 真||假 真
!假 真 假||真 真
真&&真 真 真||真 真
真&&假 假 假||假 假
假&&真 假
假&&假 假
C语言对真假的处理:非零是真;零是假
真是用1表示;假是用0(零)表示
&&(与)左边表达式为假 右边表达式肯定不会执行
||(或)左边表达式为真 右边表达式肯定不会执行
赋值运算符
= +=(a+=3等价于a=a+3) *= /=(a/=3等价于a=a/3) -=
优先级别:
算数 > 关系 > 逻辑 > 赋值
琐碎运算符【附录】:自增 自减 三目运算符 逗号表达式
- 自增[或者自减] 编程时尽量屏蔽掉前自增和后自增的差别
分类:
前自增 – ++i
后自增 – i++
异同:相同:最终都使i的值加1
不同:++i前自增整体表达式的值是i加1之后的值.
i++后自增整体表达式的值是i加1之前的值.
2. 三目运算符
格式: A ? B : C
等价于
if (A)
(B);
else
(C);
3. 逗号表达式
格式: (A, B, C, D)
功能: 从左到右执行,最终表达式的值是最后一项的值
除法/的运算结果和运算对象的数据类型有关,两个数都是int,则商就是int,若商有小数,则截取小数部分;
被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不截取小数部分。
例如:16/5==3 16/5.0==3.2 -13/4==-4 3/5==0 5/3==1
取余%的运算对象必须是整数,结果是整除后的余数,其余数的符号与被除数相同
例如:13%3==1 13%-3==1 -13%3==-1 -13%23==-13 3%5==3,
流程控制【C重点】
-
什么是流程控制
程序代码执行的顺序 -
流程控制的分类
顺序
选择
定义:某些代码可能执行,也可能不执行,有选择的执行某些代码
分类:
if
if最简单用法
格式:
if (表达式)
语句
功能:如果表达式为真,执行语句;如果表达式为假,语句不执行。
if的范围问题
(1)
if (表达式)
语句A;
语句B;
解释:if默认的只能控制语句A的执行或不执行(语句B一定会执行)
(2)
if (表达式)
{
语句A;
语句B;
}
此时if可以控制语句A和语句B
由此可见:if默认的只能控制一个语句的执行或不执行,
如果想控制多个语句的执行或不执行就必须把这些语句用{}括起来。
- if…else…的用法
- if…else if…else…的用法
格式:
if (1)
A;
else if (2)
B;
else (3)
C;
即便表达式1和2都成立,也只会执行1语句
- C语言对真假的处理
非零是真,零就是假;真用1表示,假用零表示。
-
if举例–求分数的等级
-
if的常见问题解析
循环
定义:重复执行某些代码
分类
(1)
for
格式:
for (1;2;3)
语句A;
执行的流程【重点】
单个for循环的使用
多个for循环嵌套使用(文件位置:Multiple for loops are used nested.c)
1. for (1;2;3) //1
for (4;5;6) //2
A; //3
B; //4
整体是两个语句;1 2 3是一个语句;4 是一个语句.
2. for (7;8;9)
for (1;2;3)
{
A;
B;
for (4;5;6)
}
整体是一个语句
3.范围问题数
4.例:1+2+3+…+100 1+1/2+1/3+1/4+…+1/100
(2) while
1.执行顺序
格式: while (表达式)
语句;
2.与for相互比较
for和while可以相互转换;但for的逻辑性更强,更不容易出错;推荐使用for!
for (1;2;3)
A; 等价于
1;
while(2)
{
A;
3;
}
3.举例
回文数:正着写和倒着写都一样的数. 如:121 12321 都是回文数
4.什么时候使用while,什么时候使用for
do…while 并不等价于for,当然也不等价于while(主要用于人机交互)
switch语句
switch(表达式)
{
case 常量表达式1:语句1;
break;
case 常量表达式2:语句2;
break;
default: 语句3;
break:
case 常量表达式3:语句4;
break;
}
1.所有case后面的常量表达式为便于描述暂时姑且称之为标签,这些符号都只能是
(1)枚举常量(有些称之为枚举元素),(2)数值常量,(3)字符常量,(4)常变量(const),(5)宏名中的一种,注意普通变量,枚举变量是不能作为标签使用的。
2.switch后面括号里的“表达式”允许是任何类型。
3.执行完一个case语句后,流程控制就转移到下一个case语句继续执行。“case”常量表达式
只是起语句标号的作用,并不是在该处进行语句判断。在执行switch语句时,根据switch()
中表达式的值找到与之匹配的case子语句开始执行下去,不再进行判断。
4.switch是选择不是循环,如果在switch中出现了break语句。该语句的功能只是退出switch
语句,转去执行它下面的语句。在switch中出现continue是错误的,除非switch本身就属于
for或while循环的一部分。
break 和 continue
break ((return和break的区别)
break如果用于循环中是用来终止循环
break如果用于switch,则是用于终止switch
break不能直接用于if,除非if属于循环内部的一个子语
在多层循环中 break只能终止离它最近的循环!
在多层switch嵌套中,break只能终止离它最近的switch
contiue
用于跳过本次余下的语句,专去判断是否需要执行下次循环.
数组
1.为什么需要数组
为了解决大量同类型数据的存储和使用
为了模拟现实世界
2.数组的分类
(1).一维数组
1.怎样定义一维数组
为n个变量连续分配储存空间
所有的变量数据类型必须相等
所有变量所占的字节必须相等
例: int a[5];
一维数组名(a)不代表数组中所有的元素,一位数组名(a)代表数组第一个元素的地址
2.有关一维数组的操作
1.初始化
完全初始化
int a[5] = {1,2,3,4,5};
不完全初始化,未初始化的元素自动为零
int a[5] = {1,2,3};
不初始化,所有元素是垃圾值
int a[5];
清零
int a[5] = {0};
int a[5] = {1,2,3,4,5};
int b[5]; /把a数组的值全部赋给b数组
for (i=0;i<5;i++)
b[i] = a[i];
错误写法:
int a[5];
a[5] = {1,2,3,4,5}; //错误
只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的
int a[5] = {1,2,3,4,5};
a[5] = 100; //错误:因为没有a[5]这个元素,最大只到a[4]
2.赋值
3.排序
4.求最大/小值
5.倒置 (例:Inverted array element.c)
6.查找
7.插入
8.删除
(2).二维数组
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[i][j] 表示第i+1行 第i+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},
};
操作
输出二位数组内容:(例)The use of two-dimensional arrays.c
两个for循环实现输出二维数组
(3).多维数组
并不存在多维数组,因为内存是线性一维的
n维数组可以当做每个元素是n-1维数组的一维数组
如: int [3][4];该数组是含有3个元素的一维数组,只不过每个元素都可以再分成4个小元素
函数【重点】
1.为什么需要函数
1.避免了重复性操作
2.有利于程序的模块化
2.什么叫函数
逻辑上:能够完成特定功能的独立的代码块
物理上:能够接收数据[也可不接受];
能够对接收的数据进行处理;
能够将数据处理的结果返回[也可不返回值].
总结:函数是个工具,它是为了解决大量类似问题而设计的;函数可以当做一个“黑匣子”.
3.如何定义函数 (什么是函数类型)
函数的返回值 函数的名字(函数的形参列表)
{
函数的执行体
}
1.函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体实现方法
2.return表达式;的含义:
1.终止被调函数,向主调函数返回表达式的值
2.如果表达式为空,则只终止函数,不向主调函数返回任何值
3.break是用来终止循环和switch的;return是用来终止函数的
3.函数返回值的类型也称函数类型,
因为如果函数名前面的返回值类型和函数执行体中return表达式的类型不一致的话,
则最终函数返回值的类型以函数名前的类型为准.
4.函数的分类
1.有参函数 和 无参函数
2.有返回值 和 无返回值
3.库函数 和 用户自定函数
4.值传递函数 和 地址传递函数[指针详讲]
5.普通函数 和 主函数(main函数)
一个程序必须有且只有一个主函数,主函数可以调用普通函数,普通函数不能调用主函数;普通函数可以互相
调用;主函数是程序的入口,也是程序的出口
5.需注意的问题
(1).函数调用和函数定义的顺序
如果函数调用写在了函数定义的前面,则必须加函数前置声明.
函数前置声明:
1.告诉编译器即将可能出现的若干个字母代表的是一个函数
2.告诉编译器即将可能出现的若干个字母所代表的的函数的形参和返回值具体情况
3.函数声明是一个语句,末尾必须加分号
4.对库函数的声明是通过#include<库函数所在的文件的名字.h>来实现的
1.个数相同 2.位置一一对应 3.数据类型必须相互兼容
6.如何在软件开发中合理设计函数来解决实际问题【重、难】
7.常用的系统函数
8.【专题】:递归