1,计算机的基本结构
2,什么是程序
3,程序的设计步骤
4,C库
5,计算机的数据表示
6,数据类型
7,常量
8,变量
9,数据类型的转换
-----------------------------------------------------------
1,计算机的基本结构
(1)输入输出设备:键盘,鼠标,显示屏,扫描仪。。。。
(2)CPU处理器:包含:算术逻辑运算器和控制器
CPU处理器称为计算机的大脑,控制的是计算机的执行
算术逻辑运算器:算术运算和逻辑运算,任何复杂的运算最终都会被展开成算术运算或者逻辑运算来执行
控制器:对于内存中的命令的读取以及执行
(3)存储器:
外存:硬盘,存储的是程序以及一些不着急使用的数据,容量很大,掉电不会丢失数据
内存:工作存储器,存储的程序,以及程序执行之后的结果,容量相对较小,掉电会丢失数据
寄存器:存在于CPU内部的高速存储器,容量最小,数目也很少。
注意:CPU直接是和内存进行交互。
思考:CPU和外存以及内存之间的调用关系?
(1)CPU和内存(直接调用)
(2)CPU和外存(中间经过内存)
(4)程序 :存储于计算中的一段二进制代码(可以被计算机直接识别的一组指令)
2,什么是程序?
test.c和a.out哪一个是程序?
a.out是程序
程序:
从广义上来说:为了完成一个特定的目标,所需要的一系列步骤
从计算机角度而言:一组可以被直接识别的有序指令的集合
3,程序的设计步骤:
编辑(vim)----》编译(gcc)----》执行(a.out)----》调试(GDB工具)----》编辑..........
程序设计语言的发展:
第一代:机器语言:完全由0和1组成,很难理解和记忆,工作量很大,不能移植
第二代:汇编语言:用一串便于理解的字符去标记一串01二进制指令,工作量还是很大,不能移植
第三代:高级语言:符合人的思想,用一串字符可以代替几行二进制指令,工作量较小,可以移植
面向过程:C语言
面向对象:C++ Java C#
4,C库:
理解:一些被封装好的接口,只需要调用者正确传餐使用即可
eg:scanf和 printf---》标准输入输出相关,其函数声明以及实现过程均已经被实现
man 手册---》用户的帮助文档
总共可以分为9章:
注意:前三章是我们要关心的
第一章:可执行程序和shell命令
第二章:系统调用函数(由内核提供的函数)
第三章:库函数
用法:man + 命令名称/ 函数名
5,计算机的数据表示 :
数据表示的分类:
第一类:数值数据:进位制
第二类:非数值数据:声音,字母,图片(注意:非数值数据也是以01进行存储)
字符数据(ASCII码表)
进位制:凡是以进位的方式进行运算的都称为进位制
二进制:逢二进一
范围:0-1
代表: 01101101
八进制:逢八进一
范围:0-7
代表:067
十进制:逢十进一
范围:0-9
代表:190.。。
十六进制:逢十六进一
范围:(0-9,A-F)
代表:0X3bf
进制之间的转换:
(1)十进制和二进制的关系
十进制转二进制:56 ----》 0011 1000
方法:短除法
二进制转十进制:1101 0101 ---》 213
方法:从低字节开始,乘以2的次幂(次幂从0开始),将结果相加即可
(2)八进制和十进制的关系(类似于十进制和二进制)
075 ----》61
84 ----》0124
(3)十六进制和十进制的关系(类似于十进制和二进制)
0xa5bc -----》42428
524 -----》0x20C
(4)八进制和二进制:
053
方式1:先将八进制转成十进制,再将十进制转二进制
方式2:利用8421编码(3个二进制等价于一位八进制)
0010 1011
(5)十六进制和二进制:
0xb5d
方式1:先将十六进制转成十进制,再将十进制转二进制
方式2:利用8421编码(4个二进制等价于一位十六进制)
1011 0101 1101
(6)将一个十进制的小数转为二进制
8.25
方法:先把小数点之前的按照十进制转二进制的方式进行转换,
再将小数点之后的数字乘以2,取其整数位,看其结果的小数位是否为0,如果不为0,则继续用小数点后面的数字乘以2,
直到小数点后面的数字为0截止。再将结果正着书写即可
8.25 --->
8 ----》 1000
0.25 * 2 ---》 0.5 ---》0
0.5 * 2 = 1.0 ---》 1
8.25 ----》二进制:1000.01
(6)数据类型
关键字:由系统预先定义好的一些词法符号,具有特定的含义,在C语言中,共有32个
将32位关键字进行划分为以下:
(1)基本数据类型:
char short int long float double void struct union enum
(2)控制语句:
if else switch case default break for while do continue goto
(3)存储类型:
auto register static extern
(4)类型修饰符:
const(只读) volatile(防止编译器进行优化)
(5)其他:
return signed(有符号数) unsigned(无符号数) sizeof()(测字节) typedef(取别名)
思考:sizeof是不是函数?
不是函数,是一个运算符。
1 //基于32OS下,基本数据类型所占字节大小
2 #include <stdio.h>
3
4 int main()
5 {
6 printf("sizeof(char) = %d\n",sizeof(char));
7 printf("sizeof(short) = %d\n",sizeof(short));
8 printf("sizeof(int) = %d\n",sizeof(int));
9 printf("sizeof(float) = %d\n",sizeof(float));
10 printf("sizeof(double) = %d\n",sizeof(double));
11 printf("sizeof(long) = %d\n",sizeof(long));
12 printf("sizeof(void) = %d\n",sizeof(void));
13 return 0;
14 }
运行结果如下:
linux@ubuntu:~/21051_C/day2$ ./a.out
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(float) = 4
sizeof(double) = 8
sizeof(long) = 4
sizeof(void) = 1
标识符:用户自己定义的符号,可以用于:变量名,函数名,类型名,宏名
命名规则:
(1)只能由数字,字母,下划线组成
(2)规定不能以数字开头
(3)不能与关键字重名
有符号数和无符号数:
(signed && unsigned)
有符号数:带有符号位的数字
注意:符号位一般处于开头的那个数字(即最高位的数字)
规定:
符号位为0代表正数
符号位为1代表负数
思考: 10 和-10 在计算机中的存储方式?
10 ----》 正数按照源码进行存储 0000 1010
-10 ----》 负数按照补码进行存储(补码 = 源码取反 + 1)
1000 1010(源码)
1111 0101(源码取反时,符号位保持不变)
+0000 0001
------------------
1111 0110 (补码)
分析:
(1)1和-1的存储:
(2)计算机中的存储方式为1111 1110,推算其是谁?
-2
无符号数: 没有符号位(全为有效位)
研究:基本类型的范围:
char :1个字节 == 8bit
signed char : -128 ~ 127 (-2^7 ~ 2^7-1)
unsigned char : 0 ~ 255 (0 ~ 2^8-1)
short:2个字节 == 16bit
signed short: -2^15 ~ 2^15-1
unsigned short: 0 ~ 2^16-1
浮点型数据:在内存中是以科学计数法进行存储
float:4个字节 == 32位
符号位:1个
指数位:8个
小数位:23个
精度:6-7位
double:8个字节 == 64位
符号位:1个
指数位:11个
小数位:52个
精度:15-16位
1 #include <stdio.h>
2
3 int main(int argc, const char *argv[])
4 {
5 //测试float和double的精度
6 float num = 333.333333333;
7 double num2 = 333.333333333;
8 printf("num = %f\n",num);
9 printf("num = %lf\n",num2);
10 return 0;
11 }
运行结果如下:
num = 333.333344
num = 333.333333
7,常量 :其值在程序运行期间不能被改变的数据
(1)整形常量
十进制:89
八进制:067
十六进制 :0x123
无符号长整型: 56UL
长整型:78L
(2)浮点型常量
单精度:
双精度:
(3)字符常量
'a' ,'\0' ,'\n'
(4)字符串常量
"wangjia"
(5)宏常量
格式: #define 宏名 常量值
注意:宏只是一种替换
1 #include <stdio.h>
2
3 #define Func(x) ((x) * (x))
4 int main(int argc, const char *argv[])
5 {
6
7 //printf("请输入一个数字:\n");
8 //scanf("%d",&num);
9 int ret = Func(4+6);
10 printf("%d\n",ret);
11 return 0;
12 }
总结:书写宏常量时,一定记得加括号!!
8,变量:其值在程序运行期间可以被改变的数据
变量的定义:
格式:
存储类型 数据类型 变量名;
分析:
存储类型: 标志着开辟空间的位置
数据类型: 决定了开辟空间所占字节的大小
变量名: 标志着空间的名字
局部变量:定义在大括号之内的变量
全局变量:定义在大括号之外的变量
思考:
(1) 局部变量在没有被初始化时,其值为:随机值
全局变量在没有被初始化时,其值为: 0
(2)局部变量和全局变量能否重名?
可以。
答:当全局和局部重名时,如果局部变量的生命周期没有结束,则优先使用的是局部变量
存储类型:
auto,register,static,extern
(1)auto:
被auto修饰的变量称为自动变量,可以修饰局部变量,存储在栈区
(2)register:
被register修饰的变量称为寄存器变量,可以修饰局部变量,存储在寄存器中
注意:编译器已经被优化过,会自动识别一些可能会被频繁使用到的变量吗,优先
将其存储在寄存器中,但是如果寄存器放不下,则会存储在栈区
(3)static:
被static修饰的变量称为静态变量,可以修饰全局变量,局部变量以及函数,存储在静态区
static修饰局部变量:表示可以延长该变量的生命周期,意味着被static修饰的局部变量只会被初始化一次。
static修饰全局变量:表示隐藏,只能在本文件内使用,不能被外部调用
static修饰函数:表示隐藏,只能在本文件内使用,不能被外部调用
(4)extern:
从外部调用一个全局变量或者函数
初始化 和 赋值:
初始化:在定义变量的同时给其赋值
int a = 90; //初始化
int b;
b = 89;//赋值
生命周期&作用域
生命周期:
概念:变量的产生到释放
作用域:
概念: 使用的范围
局部变量:
声明周期:从定义开始,到模块括号内
作用域:整个模块括号内有效。
全局变量:
声明周期:从定义开始,到整个程序
作用域: 作用于整个源程序。
static修饰的局部变量:
声明周期: 从定义开始,到整个程序
作用域:整个模块括号内有效。
static修饰的全局变量:
生命周期:从定义开始,到整个程序
作用域:之能在本文件内使用。
总结:
(1)除了被register以及static修饰的局部变量之外,均存储在栈区
(2)被static修饰的变量存储在静态区(具体存储在.bss还是.data依赖于有没有被初始化)
(3)static既可以修饰全局变量,局部变量,还可以修饰函数。
9,数据类型的转换:
(1)强制类型转换:(由人为自动转换的)
格式:
(数据类型)变量名;
注意:数据类型指的是目的类型
总结:强转不会引起原变量数据类型的改变!!!
(2)隐式类型转换:(编译器自动转换的)
注意观察图解!
案例:
1 #include <stdio.h>
2
3 int main(int argc, const char *argv[])
4 {
5 int a = -8;
6 unsigned int b = 6;
7 printf("a = %u\n",a);
8 if( a+b > 0)
9 {
10 printf("change to unsigned int!\n");
11 }
12 else
13 {
14 printf("change to signed int!\n");
15 }
16 return 0;
17 }
运行结果如下:
a = 4294967288
change to unsigned int!