#include 它是一个预处理指令;后面是不用加分号的因为它不是一个语句是一个预处理指令,它是一个包含文件;
它的作用是把要包含的文件的内容拷贝到当前书写 include的地方;
#include " " 包含的是一个用户定义的文件,可以是头文件,也可以是普通文件;
#include <> 包含一个系统(编译器自带)的头文件;
#include搜索的顺序:
----->当前目录------>编译器目录------>系统目录------>报错;
当前目录是指:和main.c文件同一个目录
编译器目录include目录;如果你将文件放在include里面 运行后发现没有改变,此时是因为缓存的问题
清除缓存的方法是:1.在xcode界面里面点击product-->clean;
2.找到家目录apple-->资源库-->developer-->xcode-->derivedDate 全选移到废纸篓;
模块化编程也叫多文件开发的概念:
我们把功能相似的函数封装到不同的文件中;
实现: .c c语言源文件 .h头文件
好处:1.用的时候,只需要包含.h文件,对外隐藏源文件的实现;
2.团队的分工和协作;
3.可以把功能细划分为若干个模块;
计算机中的进制:是一种计数的方式,数值的表现形式;
在xcode里面输入一个整型的二进制的数需要输入32位数字 ,因为整型占4个字节 一个字节占8位 所以是32位;输入的时候
是0b开头 后面接后面的32位数 例如二进制的13就要数如 0b00000000000000000000000000001101;
8进制的数是用o开头 16进制的数使用0x开头;用打印的方法打印8进制的16进制的数分别是用%o和%x;
进制转换的三要素:
数位:是指数码在一个数中所处的位置;例如下面的第一排就是指的第二排中每个数在这个数中所处的位置;
而第二排中各个数都叫 数码 ;
7 6 5 4 3 2 1 0
0 1 1 0 0 1 0 0
基数:045 : 基数就是8 0b00101101:基数就是2 0x520A 基数就是16; 表示按什么进制来排列就是多少基数;
位权:是数码值*基数^数位 例如上面两排中的数字 右边第一个0的位权是 数码值0*基数2^位数0 = 0;
二进制转换为十进制就是每一个位权之和; 二进制中最右侧的那个数是低位 最左边叫高位;
十进制转换为2进制是 除2取余法;例如 97转换为2进制 除2取余的方式得到 1100001 只有7位数
要变成8位才是一个字节所以在最左侧也就是高位的地方补一个0就可以了;
2进制转换为16进制:口诀是4合1:把一个二进制数,整数部分从右向左,四位合成1位;小数部分四位合成1位从左向右;例如
1000 1010 0101 .1111 这排是2进制数转换为16进制数在下一排表示
8 A 5 F 这一排就是16进制的数;
16进制转换为2进制:将16进制的每一位拆成4位二进制位;
例如 16进制的 ox520A 转换为2进制就是 5 对应0101 2对应0010 0对应0000 A对应1010;就是把每一位拆成四位表示2进制;
机器数:一个数在计算机中的二进制表示形式,叫做这个数的机器数,机器数是带符号的,在计算机用这个数的最高位存放符号整数位0,负数为1;
例如,十进制中的数+3 计算机字长为8位;转换成二进制数就是00000011。如果是-3 就是10000011;
这里的00000011 和 10000011就是机器数;
真值:因为第一位是符号位,所以机器数的形式值就不等于真正的数值,例如上面的10000011,它的最高位1代表负,它真正数值是-3;要除去符号位;
是为了区分机器数而产生的;
数据在计算机内部是以 补码 的形式储存的;
原码:一个数它的绝对值的二进制表示 如果是正 最高位也就是最左侧的那一位就改为0
如果是负数,最高位改为1;
反码:如果是正数 它的原码=反码
如果是负数 除符号位不变,其他位逐位取反 0就变为1 1就变为0;
补码:如果是正数,就等于原码;
如果是负数,就是在反码的基础上+1;
对于正数 反码=补码=原码 ; 对于负数 反码==除符号位以外的各位取反, 补码=反码+1;
例如这是8位计算机下面 [+1] =[00000001]原码 = [00000001]反码
[-1] =[10000001]原码 = [11111110]反码 =[11111111]补码
在64位的机器下 +1的表示为
原码是:00000000000000000000000000000000000000001
反码==原码
补码==原码
-1的表示为:
原码是10000000000000000000000000000001;
反码是11111111111111111111111111111110;
补码是11111111111111111111111111111110+1 最后就是11111111111111111111111111111111;
实例将-13的原码 反码 补码分别表示出来;
第一步
原码:10000000000000000000000000001101;
第二步
反码:11111111111111111111111111110010;
第三步
补码:11111111111111111111111111110011;
引入补码的原因是:1.计算机能够做减法,2、计算机的电路设计更简单;
位运算:用于整数的二进制位之间的运算;
&按位与:两个数进行按位与运算用2进制表示出来之后 两个数同1为1 ,否则为0 例如
9&4用二进制分别表示是 00001001 最后与完之后就是00000000;
00001000
实用性 :1、获取一个数的最低位,让这个数和1进行按位与操作;因为1是00000001 所以在1前面的数一与就全是0,
如果与的那个数最后位是1与的结果就是1 如果是0那就是0
|按位或:如果两个数进行按位或操作有1就为1 同0才是0;就像上个例子假如是9|4 答案就是
00001001;
~按位取反:1变0, 0变1;还是上面那个例子假如~9 那么答案是 11110110;
>> 右移位:各2进制位全部右移n位 高位补0;右移位,移出去的部分要舍弃,高位时补符号位如果是正数是补1,负数是补0;
8>>2=8/2^2=2;一个数右移多少位它的值就等于原值除以2^n;
右移不会改变一个数的正负性;
<<左移位:各2进制位全部左移n位 ,左侧移出去的n位就丢了,这样不够32位了就会在低位也就是右侧补0;例如
8<<2就表示左移两位=8*2^2=32
记忆的技巧是:向左移动n位,相当于原数*2^n;
左移可能会改变一个数的正负性;
^ 按位异或:相同为0 不同为1;例如9^8答案就是00000001;
写一个函数把10进制数按照二进制格式输出:
思路:1.让n 右移i位;2.让n移动i位之后的结果与1与;3.打印与的结果;
#include <stdio.h>
/*
传递整数n,用二进制表示
*/
void changeTo2(int n){
int len =sizeof(n)*8;//获取位数;
int i ;
int temp ;
for (i=0;i<len;i++){
temp = n ; //每次循环n这个数;
temp>>31-i; //依次右移31位 30位..... ;
int t =temp & 1; //用temp与1进行与操作获取每一位数;
printf("%d",t);
}
}
int main(){
changeTo2(13);
return 0;
}
如何判断一个数是奇数还是偶数:
分析:如果一个数与1进行于操作 那么结果如果是1 那么证明它就是奇数, 如果结果是0结果就是偶数;
#include<stdio.h>
void jiou(int n){
if(n&1){
printf("奇数\n");
}else{
printf("偶数\n");
}
}
int main(){
jiou(3);
return 0;
}
实现两个变量值变换:
/* 用按位异或实现两个变量的位置交换;
#include<stdio.h>
int main(){
int a= 3;
int b= 4;
a = a^b; //按位异或之后它的值就等于a+b;
b = a^b; //按位异或之后b的值就变成a+b-b=3;
a = a^b; //按位异或之后a的值变成了a+b-b=4;从而实现了位置的交换;
printf("%d,%d",a,b);
return 0;
}
*/
输出一个地址使用%p来实现;一般是假如定义了一个 int num = 10;printf("%p",&num)这么来表示 不然就是用指针 int *p =&num 就表示指向num的地址;
计算机分配内存的时候:是从高地址向低地址分配,先定义的变量,分配的是高地址,后定义的变量,分配的是低地址;
高字节<-------------- ------------->低字节
变量的存储细节:1、低字节(低位),存放在低地址,高字节(高位),存放搞地址;例如4的二进制为00000000 00000000 00000000 00000000 (00000100)括号内叫首地址
内存地址: 内存单元:
0x01 :这里是低地址:存放4的低字节为00000100 这里也叫4的首地址;
0x02
0x03
0x04 :这里是高地址:存放4的高字节为00000000
变量的地址:变量的首地址(变量在内存中占用的存储单元(也叫一个字节)中地址最小的那个地址也就是低地址;)
查看变量在内存中的每一个字节:
#include<stdio.h>
int main(){
int num =10;
char *p =# //指针 指向num的的地址 &num的意思就是保存num的地址
printf("第一个字节的地址:%p ,%d\n",p,*p);
printf("第二个字节的地址:%p ,%d\n",p+1,*(p+1)); //这里要用小括号把*(p+1)括起来表示第二个字节
printf("第三个字节的地址:%p ,%d\n",p+2,*(p+2));
printf("第四个字节的地址:%p ,%d\n",p+3,*(p+3));
return 0;
} |
|