20240328,位运算,可变数组,链表(我是真的没有听懂)

位运算

一,按位运算

按位运算,把整数当作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<stdio.h>
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<<j,  i中所有的位向左移动i个位置,而右边填入0
所有小于int的类型,移位以int的方式来做,结果是int
x<<= 1等价于x*=2
x<<= n等价于x*= 2^n 

最多可以移位多少,取决于INT多大

#include<stdio.h>
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<stdio.h>
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<stdio.h>
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<stdio.h>
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 <stdio.h>
#include <stdlib.h>
#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<a->size;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 <stdio.h>
#include <stdlib.h>
#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月到来之前能学懂

 

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值