位运算

一,按位运算

按位运算,把整数当作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;isize;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月到来之前能学懂

 

精彩链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。