周二笔记
ASCII
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)
在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。
类型说明符
类型说明符
类型说明符一般都是用于修饰int类型的
1.说明长度的
short
long
long long
2.说明符号位的
unsigned 无符号的:
不把二进制的第一位当做符号位来使用, 所以只能存储零和正数, 不能存储负数
注意点: 如果变量被unsigned修饰了, 那么取出的时候必须使用%u, %u就代表用无符号的方式取出
应用场景: 存储银行存款, 学生的分数等不能出现负数的情况
signed 有符号的:
默认int就是有符号的, 就可以保存负数,零,正数, 所以signed一般用不上
排序
- 观看视频增加对排序算法的理解
选择排序: https://v.youku.com/v_show/id_XMzMyODk5MDI0.html
冒泡排序: https://v.youku.com/v_show/id_XMTY0NjQ2NDE0MA==.html
插入排序: https://v.youku.com/v_show/id_XMTY0NjQ2ODY5Ng==.html
希尔排序: https://v.youku.com/v_show/id_XMTY0NjQ2NzI5Mg==.html
冒泡排序
1.选择排序, 每一次都是用某一个元素和后续所有元素比较, 经过一轮比较之后最值出现在最前面
2.选择排序的实现步骤
2.1 实现打印倒三角
2.2 实现输出需要比较的索引
2.3 添加判断条件, 交换位置
3.冒泡排序, 每一次都是用相邻的两个元素进行比较, 经过一轮比较之后最值出现在最后面
4.冒泡排序的实现步骤
4.1 实现打印倒三角
4.2 实现输出需要比较的索引
4.3 添加判断条件, 交换位置
插入排序
每次都是用后一个元素和前面所有的元素进行比较
一旦发现后一个元素小于前面一个元素就让前面一个元素向后移动
或者一旦发现后一个元素大于前面一个元素就让当前元素插入到前面一个元素后面
// 1.实现从第1个元素开始取出, 和前面所有的元素进行比较
for(int i = 1; i < 4; i++){
printf("i = %i\n", i);
// 2.取出用于和其它元素比较的元素
int temp = nums[i]; // i = 1; temp = 2
int j = i; // j = 1; j = 0;
while(j > 0){
printf("%i, %i\n", i, j - 1);
if(temp < nums[j - 1]){ // 2 < 3
// 3.如果当前元素小于前面一个元素, 让前面一个元素后移一位
// nums[1] = nums[0]; num1 = 3
nums[j] = nums[j - 1];
}else{
// 4.如果当前元素大于前面一个元素, 将当前元素插入到前面一个元素后面
break;
}
j--; // j = 0;
}
// nums[0] = 2;
nums[j] = temp;
}
函数的形参
// 一定要记住, 不要管实参传递的是什么, 只看形参就可以了
// 如果形参时基本数据类型, 那么在函数内修改形参不会影响到外界的实参
// 如果形参是数组, 那么在函数内修改形参会影响到外界的实参
指针
什么是地址?
现实生活中 天津市城关镇长安路123号501
在编程开发中 变量说占用内存空间的地址
地址有什么用?
显示生活中, 我们是不是可以根据地址, 找到对应的房间
在编程开发中, 也可以根据地址找到对应的内存空间
指针变量?
指针变量和普通变量一样, 都是用来保存数据的
只不过和普通变量有一点区别, 普通变量可以保存int/char/float/double等类型的数据
指针变量只能保存内存地址
简而言之, 指针变量, 就是专门用于保存内存地址的变量
定义指针变量的格式:
数据类型 变量名称; // 定义一个普通变量
数据类型 *变量名称; // 定义一个指针变量
指针为什么要有类型?
由于指针变量指向的是某一个变量占用存储空间的首地址
所以在获取指向变量中存储数据的时候, 指针是不知道要获取多少个字节的数据的
所以指针变量的数据类型的作用, 就是告诉指针, 在获取指向变量的数据的时, 需要获取几个字节的数据
无论是什么类型的指针变量在相同的编译器下占用的内容都相同
32位编译器下4个字节
64位编译器下8个字节
函数指针
指向函数的指针
计算机也会给函数分配存储空间, 既然函数会分配内存空间,
所以函数也有自己的地址, 所以指针变量也可以保存函数的地址
经过前面的学习, 我们知道数组名保存的就是数组的地址
函数和数组很像, 函数名中保存的就是函数的地址
如何定义指针变量?
1.将需要保存变量的定义拷贝过来
2.在数据类型和变量名称中间添加一个*
3.修改变量名称
如何定义保存函数的指针变量
1.将函数的什么拷贝过来
2.在函数返回值和函数名称总监添加一个*
3.修改函数名称
4.注意点: 需要将*和变量名称用括号括起来
我们说过指向函数的指针和指向数组的指针很像
如果是数组, 我们可以直接将数组名称赋值给一个指针变量
如果是函数, 我们也可以直接将函数名称赋值给一个指针变量
如果一个指针指向了数组, 那么访问数组就有了三种方式
数组名称[索引];
指针变量名称[索引]
*(指针编码名称 + 索引)
如果一个指针指向了函数, 那么访问方式也有多种方式
函数名称();
(*指针变量名称)();
指针变量名称();
结构体
什么是结构体?
结构体时构造类型的一种
构造类型前面我们已经学习过了数组:
数组的作用是用于存储一组相`同类型`的数据
结构体的作用是用于存储一组`不同类型`的数据
保存一个人的信息
姓名/年龄/身高 ...
char *
int
double
如何定义结构体变量
1.先定义结构体类型
2.通过结构体的类型定义结构体变量
如何定义结构体类型?
struct 结构体类型名称{
数据类型 属性名称;
数据类型 属性名称;
... ...
};
如何定义结构体变量
struct 结构体类型名称 变量名称;
如何访问结构体的属性
结构体变量名称.结构体属性名称;
结构体内存分析
注意点:
给整个结构体变量分配存储空间和数组一样, 从内存地址比较大的开始分配
给结构体变量中的属性分配存储空间也和数组一样, 从所占用内存地址比较小的开始分配
注意点:
和数组不同的是, 数组名保存的就是数组首元素的地址
而结构体变量名, 保存的不是结构体首属性的地址
共用体
共用体
共用体的格式:
union 共用体名称{
数据类型 属性名称;
数据类型 属性名称;
... ...
}
共用体定义的格式和结构体只有关键字不一样, 结构体用struct,共用体用union
共用体特点:
结构体的每个属性都会占用一块单独的内存空间, 而共用体所有的属性都共用同一块存储空间
只要其中一个属性发生了改变, 其它的属性都会受到影响
应用场景:
同一个变量, 在不同的时刻,需要表示不同类型数据的时候, 我们就可以使用共用体
枚举
枚举?
枚举用于提升代码的阅读性, 一般用于表示几个固定的值
所以还有一个名称, 叫做枚举常量
如果某些变量的取值是固定的, 那么就可以考虑使用枚举来实现
枚举的格式:
enum 枚举类型名称{
取值1,
取值2,
};
注意点: 和结构体,共用体不同, 枚举是用逗号隔开
规范:
枚举的取值一般以K开头,后面跟上枚举类型名称, 后面再跟上表达的含义
K代表这是一个常量
枚举类型名称, 主要是为了有多个枚举的时候, 方便区分
含义, 你想表达的意思
枚举的取值:
默认情况下从0开是取值, 依次递增
也可以手动指定从几开始, 依次递增
枚举类型的作用域:
和结构体类型的作用域一样, 和变量的作用域一样
枚举类型变量的多种定义方式
和结构体类型的多种定义方式一样
局部变量 && 全局变量
局部变量:
概念: 定义在{}中,函数中,形参都是局部变量
作用域: 从定义的那一行开始, 直到遇到}结束或者遇到return为止
存储的位置: 局部变量会存储在内存的栈区中, 会随着定义变量的代码执行分配存储空间, 会随着作用域的结束自动释放
特点:
相同作用域类, 不能出现同名的局部变量
如果不同作用域内有相同名称的变量, 那么在访问时, 内部的会覆盖外部的(就近原则)
全局变量:
概念: 定义在{}外或者函数外的变量, 都是全局变量
作用域: 从定义的那一行开始, 直到文件末尾
存储的位置: 全局变量会存储在内存的静态区中, 会随着程序的启动分配存储空间, 随着程序的结束释放存储空间
特点:
如果有多个同名的全局变量, 那么也只会分配一次存储空间, 多个同名的全局变量共用同一块存储空间
修饰变量
/*
* auto,
* register,
* extern,
* static
*/
/*
* auto和register都是用于修饰局部变量的
* 它们年的作用是修饰编程的存储特性
* auto: 特点就是告诉编译器, 局部变量离开作用域自动释放
* 默认情况下所有局部变量都是auto的, 所以这一句废话, 所以了解--> 忘记 / 即可
*
* register: 特点就是告诉编译器, 将局部变量存储到CPU寄存器中
* 好处就是访问的速度会更快, 但是在不同平台,不同编译器下, 会做不同的优化, 所以还是一句废话, 所以了解 --> 忘记 / 即可
* static对局部变量的作用
* 如果利用static修饰局部变量, 那么会将局部变量的存储区域从栈区移动到静态区
* 静态区只有程序结束才会释放
* extern对局部变量的作用
* extern用于声明一个变量, 声明变量并不会开辟存储空间
* extern一般用于全局变量, 至今没见过有人用extern来修饰局部变量
*
*
* extern对全局变量的作用
* extern用于声明一个变量, 声明变量并不会开辟存储空间
* exter只能用于全局变量, 不能用于局部变量
*
* 原因:
* 局部变量, 只有执行到那一行代码才会分配存储空间, 所以哪怕声明了 ,但是在使用时还是没有分配, 所以还是不能存储数据
* 全局变量, 会随着程序的启动分配存储空间, 所以只要声明了, 使用时已经分配好了存储空间, 一定能够使用, 一定能够存储数据
* static对全局变量的作用
* 定义一个内部的全局变量,
* 1.该变量只能在定义的文件中使用, 不能在其它文件中使用,
* 2.并且该变量会独占一块内存空间
*
* 全局变量的特性:
* 可以定义多个同名的全局变量, 多个同名的全局变量共享一块内存空间
* 哪怕不是同一个文件中的同名全局变量, 也会共享同一块内存空间
* extern和static对函数的作用
* 1.如果利用extern修饰函数, 代表这是一个外部函数, 其它文件中也可以使用
* 注意点: 默认情况下所有函数都是外部函数, 所有的函数都可以在其它文件中访问, 所以extern是一个废物
*
* 如果利用static修饰函数, 代表这事一个内部函数, 只能在当前文件中使用
* 如果一些内部函数不想提供给外界使用, 那么就可以给函数添加一个static
*/