位运算
一,按位运算
按位运算,把整数当作2进制的数字进行运算? &按位与,|按位或,~按位取反,^按位的异或,<<左移, >>右移
1.1 &按位与
·如果(x)i==1并且(y)i==1,那么(x&y)=1 否则的话(x & y)i=0 按位与常用于两种应用: ·让某一位或某些位为 0 : x & 0xFE·取一个数中的一段: x & 0xFF
1.2 |按位或
如果(x)i== 1或(y)i== 1,那么(x|y)i= 1 否则的话,(x|y)== 0 按位或常用于两种应用:使得一位或几个位为1: x | 0x01 把两个数拼起来: 0x00FF I 0xFF00
1.3 ~按位取反
(~x)i= 1 -(x)i 把1位变0,0位变1 想得到全部位为1的数:~0 7的二进制是0111,x7使得低3位为1,而 x&~7,就使得低3位为0和补码不一样补码是用1减?
#include
int main(){
unsigned char c=0xAA;
printf("c=%hhx\n",c);
printf("~c=%hhx\n",(char)~c);//~-的运算结果是INT,希望看到字节大小的整数输出?类型转换
printf("-c=%hhx\n",(char)-c);
//aa,55,56
return 0;
}
对于逻辑运算,它只看到两个值:0和1可以认为逻辑运算相当于把所有非0值都变成1,然后做按位运算 5 & 4->4而5&&4->1&1->1 5 | 4->5而5/4->111->1 ~4->3而!4->!1->0
1.4 ^按位的异或
如果(x)i==(y)i,那么(x^ y)i= 0否则的话,(x^ y)i== 1如果两个位相等,那么结果为0;不相等,结果为1 如果x和y相等,那么x^y的结果为0 对一个变量用同一个值异或两次,等于什么也没做x^y^y->x
二,移位运算
2.1 <<左移
i< #include int main(){ unsigned char c=0xA5; printf(" c=%x\n",c); printf("c<<2=%x\n",c<<2); printf(" c=%d\n",c); printf("c<<2=%d\n",c<<2); return 0; } 2.2 >>右移 i >> j i中所有的位向右移j位 所有小于int的类型,移位以int的方式来做,结果是int 对于unsigned的类型,左边填入0 对于signed的类型,左边填入原来的最高位(保持符号不变)x>>= 1 等价于x /= 2 x>>= n等价于 x /= 2^n #include int main(){ int a=0x80000000;//4字节的整数所能表达的最大的负数,高位为1,负数 unsigned b =0x80000000; printf("a=%d\n",a); printf("b=%u\n",b); printf("a>>1=%d\n",a>>1); printf("b>>1=%u\n",b>>1); //左移不管符号位 printf("a<<1=%d\n",a<<1); printf("b<<1=%u\n",b<<1); return 0; } 移位的位数不要用负数,这是没有定义的行为 x<< -2 //!!NO!! 三,位运算例子 3,1 输出一个数字的二进制 #include int main(){ int num; scanf("%d",&num); unsigned mask=1u<<31; //unsigned ,,,mask==unsigned int mask,省略 //1最低位为1,U是一个UNSIGNED的数,左移31位 //其实就是0X80000000,最高位为1的这个东西? for( ;mask;mask>>=1){ printf("%d",num&mask?1:0); //依次右移,每次结果和MAASK取余? //逐一检查每一位是0 OR 1 } printf("\n"); return 0; } 3.2 MCU的SFR--不懂 什么单片机的特殊功能寄存器??? 四,位段--不懂 上一小节的东西?只能控制一个比特,不能控制多个 位段——类似结构的结构,成员后面冒号+数字,表示这个成员占几个比特 把表的内容变成一个位段里面的一个个变量? #include struct U0{ unsigned int leading:3; unsigned int FLAG1:1; unsigned int FLAG2:1; int trailing:27;//3+1+2+27=32 }; void prtBin(unsigned int number); int main(){ struct U0 uu; uu.leading=2; uu.FLAG1=0; uu.FLAG2=1; uu.trailing=0;//初始化 printf("sizeof(uu)=%lu\n",sizeof(uu)); prtBin(*(int*)&uu);//把UU当作一个整数,输出2进制 //取得uu的地址,&UU是一个指向U0的指针,强制类型转换为指向INT的指针 //再取指针,取得一个INT return 0; } void prtBin(unsigned int number){ unsigned mask=1u<<31; for( ;mask;mask>>=1){ printf("%d",number&mask?1:0); } printf("\n"); } sizeof(uu)=4,最后5位是10010,1-0-010 ==FLAG2-FLAG1-leading,【写错FLAG2:2的时候,sizeof(uu)=8,所有的位段加起来超过32了,需要两个INT来表达他】 可以直接用位段的成员名称来访问,比移位、与、或还方便 编译器会安排其中的位的排列,不具有可移植性 当所需的位超过一个int时会采用多个int 用于比较底层的操作硬件的场所 可变数组--不懂 一,可变数组 可调整大小的阵列 考虑一组提供可调整大小的int数组机制的函数。 1,可生长的,2, 获取当前大小,3,对元素的访问 通过函数实现可增长数组的机制create创建数组 free回收空间 size单元数量 at访问单元【数组可以读也可以写,可以做左值也可以做右值……】 INFLATE核心形式,让数组长大 定义的时候不要直接定义指针,指针虽然在传入函数的时候比较方便,但是指针使用的时候想调用一个变量,他是从某个地方调出来的,不是本地变量,看起来也充满欺骗性说用指针有两个风险,1是如果A指向NULL,2是如果A已经指向了一个有的数组,那么还要先做FREE的事情……抽象,感觉后面几节课听的都是“呵呵呵他在说些什么” 二,可变数组的数据访问,自动增长--不懂 我真的,根本听不明白还听着男神 “ 嗯哼~ ” #ifndef _ARRAY_H_ #define _ARRAY_H_ typedef struct{ int *array; int size; }Array; //不要直接定义指针 Array array_creat(int init_size); void array_free(Array *a); int array_size(const Array *a); int* array_at(Array *a,int index); void array_inflate(Array *a,int more_size); #endif MALLOC出来的东西不能长大,我们重新申请一块新的空间 前面还跑着,后面两个函数就错了,我也不知道错哪里不懂代码在干什么根本无力调试…… #include #include #include "araay.h" const BLOCK_SIZE=20; //typedef struct{ // int *array; // int size; //}Array; Array array_creat(int init_size) { Array a; a.size=init_size; a.array=(int*)malloc(sizeof(int)*a.size); return a; //返回一个本地变量? } void array_free(Array *a) { free(a->array); a->array=NULL;//保险,防止别人调两次 a->size=0; } //封装,把a保护起来了,也许随着算法改进,A的SIZE不能直接给你? //把内部的实现细节保护起来,你不知道我怎么做的? int array_size(const Array *a) { return a->size; } //为什么返回指针 int* array_at(Array *a,int index) { if(index>=a->size){ //array_inflate(a,index-a->size+1); //每次长一个,太慢,一个单位BLOCK的概念 array_inflate(a,(index/BLOCK_SIZE+1)*BLOCK_SIZE-a->size+1); // 从1开始数的序号? }//越界,还有-1的情况没写 return &(a->array[index]); } //给接受不了的 int array_get(const Array*a,int index) { return a->array[index]; } void array_set(Array *a,int index,int value) { a->array[index]=value; }//end void array_inflate(Array *a,int more_size) { int *p=(int*)malloc(sizeof(int)(a->size+more_size));//error int i; for(i=0;i p[i]=a->array[i]; }//遍历拷贝,可以用标准库MEMCTY替代,效率更高 free(a->array); a->array=p; a->size+=more_size; } int main(int argc, char *argv[]) { Array a=array_creat(100); //函数返回的是一个结构,可以赋值 printf("%d\n",array_size(&a)); //printf("%d\n",a.size); *array_at(&a,0)=10;//做赋值,a[0]位置上的值 ,*函数调用 ,接受不了就 printf("%d\n",*array_at(&a,0)); int number; int cnt=0; while(number!=-1){ scanf("%d",number); if(number!=-1) *array_at(&a,cnt++)=number; //scanf("%d",array_at(&a,cnt++)); } array_free(&a); return 0; } 我真的,后面的讲义放的都是英文,我怕我听懂了吗 链表--全不懂 一,可变数组的缺陷 每次膨胀时分配新内存是一种简单而干净的方法【每次都需要重新申请一块内存,全部拷贝】。但是复制需要时间,而且在内存受限的情况下可能会失败可能还有那么多空间,但是,没有办法申请这么多内存了 二,链表 HEAD,链表,结节 #ifndef _NODE_H_ #define _NODE_H_ typedef struct _node { int value; struct _node*next;//第6行没有Node出现 }Node; #endif #include #include #include "node.h" //typedef struct _node { // int value; // struct _node*next; //}Node; int main(int argc, char const* argv[]) { Node*head=NULL; int number; do{ scanf("%d",&number); if(number!=1){ //add to linked-list Node*p=(Node*)malloc(sizeof(Node)); p->value=number; p->next=NULL;//这是最后面的一个,新的一个 //find the last Node*last=head; if(last){ while(last->next){ last=last->next; } //只要last指向有东西,那么就会一直循环,最后一个指向NULL,0循环停下 //attach last->next=p; }else{ head=p;//第一个是一个特殊的情况 } } }while(number!=1); return 0; } 三,链表的函数 神他的四种还是五种办法……呵呵不懂……炒一下代码得了 ……算了,剩下几节先放放,我补一下前面的东西,刷点题,听都听不懂也不是办法 苦笑,哀嚎,扭曲 四,链表的搜索 五,链表的删除 六,链表的清除 呵呵,希望我4月到来之前能学懂 精彩链接
发表评论