郝斌C语言学习笔记
用c语言实现:
1.判断一个数字是否是素数
2.判断一个数字是否是回文数
3.实现一个十进制数字的二进制形式
4.求一个数字的每位是奇数的数字取出来组合形成新的数字
5.求一个数倒过来的数
看懂一个程序分3步:1.整个程序的流程 22.语句的功能 3.试数(自己去改,换一种表达)
230517
1、浮点数的存错所带来的问题
float和double都不能保证可以精确地存储一个小数
例子:
判断浮点型变量x是否为0
if (abs(x - 0.000001) < 0.000001)
yes;
else
no;
为什么循环中更新的变量不能定义为浮点型
2、自增自减:前缀用新值,后缀用旧值,但是表达式最终都会+1
注意:
(1)自增的目的:代码更精炼;速度更快
(2)编程时尽量避免屏蔽掉前自增和后自增的差别
(3)自增表达式最好不要作为一个更大的表达式的一部分来使用;最好独立成句,不然不可移植
如: int m = i ++ + ++i + i ++;
3、逗号表达式,从左到右执行,最后一个表达式为整个表达式的值
如 : i= (a= 3 +5 ,b = 1 + 1,c = 5);//即 i 的值为 c
4、break跳出循环;continue结束此次循环更新变量后进入下次循环
5、switch分支,不是循环不能用continue;某个case匹配之后不再匹配,从匹配处一直往下执行(包括default)一直到结束。不想往下执行用break结束switch语句;defaul可以不写
6、数组
数组不初始化时是垃圾值。
初始化分为完全初始化和不完全初始化,不完全初始化时未初始化的值为0.
只有在定义数组时才能整体赋值:
int a[5] = {1, 2, 3, 4, 5}; //right
int a[5]; a[5] = {1, 2, 3, 4, 5} //error
把数组a的值全部复制给b:
正确: for (i = 0; i < 5; i ++ ) b[i] = a[i];
错误: b = a; //error
一维数组名 代表 数组第一个元素的地址
printf(“%-5d”, n); // " - "表示左对齐
多维数组
不存在多维数组,因为内存是线性一维的
n维数组可以当做每个元素是n-1维数组的一维数组
如: int a[3][4】
7、函数(C语言的第二个重点,函数是c语言的基本单位):
为什么需要函数:
(1、避免重复性操作
(2、有利于程序的模块化,大功能分成小功能独立实现(面向过程的的体现之一)
函数的定义:
(1) 逻辑上:能够完成特定功能的独立代码块
(2) 物理上:
可以接收数据(也可以不接收
可以对接收的数据进行处理
可以返回处理的结果(也可以不反回
总结:函数是一个工具,它是为了解决大量类似问题而设计的
函数类型以定义时为主,与return 无关
230521
函数的分类:
有参函数 和 无参函数
有返回值函数 和 无返回值函数
库函数 和 自定义函数
普通函数 和 主函数
一个函数必须有且只有一个主函数
主函数可以调用普通函数,反过来不行;普通函数可以互相调用
变量类型(按存储方式):1)静态变量 2)自动变量 3)寄存器变量
推荐参考书《turboc2.0实用大全》-机械工业出版社
8、C语言32个关键字
1、auto:声明自动变量,一般不使用。
2、break:跳出当前循环。
3、case:开关语句分支。
4、char:声明字符型变量或函数。
5、const:声明只读变量。
6、continue:结束当前循环,开始下一轮循环。
7、default:开关语句中的“其他”分支。
8、do:循环语句的循环体。
9、double:声明双精度变量或函数。
10、else:条件语句否定分支。(可与if连用)
11、enum:声明枚举类型。
12、extern:声明变量是在其他文件正声明。
13、float:声明浮点型变量或函数。
14、for:循环当中的一种语句。
15、goto:无条件跳语句。
16、int:声明整型变量或函数。
17、if:条件语句。
18、long:声明长整型变量或函数。
19、register:声明寄存器变量。*
20、return:子程序返回语句(可以带参数,也可以不带参数)。
21、short:声明短整型变量或函数。
22、signed:生命有符号类型变量或函数。
23、sizeof:计算数据类型长度。
24、static:声明表态变量。*
25、struct:声明结构体变量或函数。
26、switch:用于开关语句。
27、typedef:用以给数据类型取别名(当然还有其他作用)。
28、union:声明联合数据类型。
29、unsigned:声明无符号类型变量或函数。
30、void:声明函数无返回值或无参数,声明无类型指针。
31、volatile:说明变量在程序执行中可被隐含地改变。*
32、while:循环语句的循环条件。
20230601
指针(变量):C语言的灵魂
指针可以表示一些复杂的数据结构
快速的数据传递
能直接访问硬件
能够方便地处理字符串
是理解面向对象语言引用的基础
1)指针就是地址,地址就是指针,地址是内存单元的编号
2)指针变量是存放地址的变量
3)指针和指针变量是两个不同的概念
如何通过被调函数修改主函数普通变量的值:
1.实参必须为改普通变量的地址
2.形参必须为指针变量
3.在被调函数中通过
形参名 = …
的方式就可以修改主调函数相关变量的值
2.指针和数组
指针和一维数组
一维数组名: 是一个指针常量,存放的是第一个元素的地址
下标和指针的关系:如果p是一个指针变量,则
p[ i ] 永远等价于 *(p + i)
确定一个一维数组需要几个参数:2个
指针变量的运算:只能相减。并且两个指针变量指向的是同一块连续空间中的不同存储单元,才可以相减。
一个指针变量到底占几个字节
sizeof(数据类型)
功能:返回值就是该数据类型所占的字节数
假设p指向char类型变量( 1个字节 )
假设q指向int类型变量(4个字节 )
假设r指向double类型变量(8个字节 )
p q r 本身所占的字节数是一样的!!!
总结:一个指针变量,无论它指向的变量占几个字节;该指针变量本身只占4个字节(devc++ 显示占8个字节)
指针和二维数组
230604
专题:动态内存分配
传统数组的缺点:
1、该数组的内存程序员无法手动释放,只能等到数组所在的函数运行结束。
2、数组一旦定义,长度不能再改变
3、传统方式定义的数组不能跨函数使用
4、数组长度不能用变量表示(C99好像可以了)
为什么需要动态分配内存?
1、可以解决传统数组的4个缺陷,传统数组也叫静态数组
2、动态分配的内存可以跨函数使用,
动态内存分配举例—动态数组构造 :
动态内存和静态内存的比较
静态内存是由系统自动分配,由系统自动释放;动态内存是由程序员手动分配,手动释放
静态内存是在栈分配的;动态内存是在堆分配的
结构体(230605)
定义结构体的3种方式:
//第一种 推荐!!!
struct Student
{
int age;
float score;
char sex;
};
//第二种
struct Student
{
int age;
float score;
char sex;
} st2;
//第一种
struct
{
int age;
float score;
char sex;
} st3;
怎样使用结构体变量
赋值和初始化:
// 第一种,只定义了类型, 没有定义变量
struct Student st= { 80, 66.6, 'F'};
// 第二种
struct Student st2;
st2.age = 18;
st2.score = 99.9;
st2.sex = 'M';
//第三种
struct Student st3;
struct Student * pst = &st3;
st3->age = 20;
st3.score = 88.8;
// pst->age 在计算机内部会被转化成(*pst).age; 这就是->的含义
//pst->age 等价于 (*pst).age 等价于 st.age
**pst->age 在计算机内部会被转化成(pst).age; 这就是->的含义;pst->age 等价于 (pst).age 等价于 st.age
1、结构体变量名.成员名
2、指针变量名->成员名
如何去除结构体变量中的每一个成员
结构体变量的运算
不能相加,不能相减,不能乘除;但可以互相赋值
结构体变量和结构体变量指针作为函数参数传递的问题
举例
动态构造存放学生信息的结构体数组
动态构造一个数组,存放学生的信息
然后按分数排序输出
链表:
枚举
什么是枚举
怎样使用枚举
枚举的优缺点
使代码更安全,但也更麻烦
位运算符
补码