翁恺C语言基础学习——位运算概念,自定义容器
C语言位运算符
-
‘&’ —— 按位与 ,'(x)i == (y)i ==1 则--> (x & y ) i=1,否则(x & y ) =0 ',也就是两个二进制数两位都都为1时,则为1 ,否则为0
-
‘|’ ——按位或 , '(x)i=1 或者 (y)i =1 则--> (x | y)i =1' 两个二进制数两位只要有一个不为0,则为1,否则为0
-
‘~’ ——按位取反, '~(x)i = 1-(x)i' , 把1位变成 0, 0位变成1 ,
-
‘^’—— 按位异或 '(x) i=(y)i 则 (x)i ^ (yi) =0 否则为 1' 任何一个数 用同一个值异或两次,等于原来的自己
-
'<<'——左移运算 'i << j' 将 'i'中所有的位向左移动'j'个位置, x<<1 == > x *=2 x<< n ==> x *= 2的‘n’次方, 所有小于int类型的值,移位以int方式来做,结果是int
-
'>>'——右移运算 ' i>> j' 将 'i'中所有的位向右移动'j'个位置, x>> 1 ==> x /=2 , x>>n ==> x /= 2的'n'次方!所有小于int类型,移位以int方式来做,结果是int,对于 unsigned类型左边填入0,有符合位,则符号位不变
位移不能使用负数 ,未定义的行为
void print_bit(int n); void print_unsigned_bit(unsigned n); //按位的与 void test_bit_with_and() { //应用一:让某一位或某些位为0 如:x & 0xFE (0xFE-->1111,1110,进行位运算后这个数的最后一位就为0) int a = 33; print_bit(a); int res = a & 0xFE; //(32-->'0010,0001' & '1111,1110' ===> 0010,0000) print_bit(res); printf("%d\n", res); //应用二:获取某个数当中的一段: x & 0xFF (0xFF-- > '1111,1111', 位运算后 得出这个数最后8位的值) int data =0xfffe ; print_bit(data); //输出 binary->1111,1111,1111,1110 data = data & 0xff; //取后8位 print_bit(data); //输出 binary-->1111,1110 } //按位或 void test_bit_with_or() { //应用一:使得一位,或者几位为 1 int data = 0xAA; //binary --> 1010,1010 int data1 = 0x54; //binary --> 0101,0100 data = data | data1; print_bit(data); //binary --> 1111,1110 //应用二:把两个数拼接起来 data = 0xff00; //binary -->111,1111,0000,0000 data1 = 0x00ff; //binary -->0000,0000,1111,1111 data = data | data1; print_bit(data); //binary -->111,1111,1111,1111 } void test_bit_with_xor() { //应用,简单的数据加密,解密 int data = 0xAA; //binary --> 1010,1010 int data1 = 0x54; //binary --> 0101,0100 data = data ^ data1; data = data ^ data1; print_bit(data); //binary --> 1010,1010 } /* 打印二进制数据 */ void test_mybitprintf(int number) { if (number == 0) { printf("binary-->%d", 0); return; } unsigned int mask = 1u << 31; //int类型4个字节,无符号 左移31位则 1000,0000,0000,0000,0000,0000,0000,0000 printf("%d-binary===>", number); //直到mask 右移32位 得到结果 0 时,for循环退出 for ( ; mask; mask >>= 1) { // (1000,0000,0000,0000,0000,0000,0000,0000) & (0000,0000,0000,0000,0000,0000,0000,0010) // 得出结果===> 0000,0000,0000,0000,0000,0000,0000,0000 非零才为真,直到倒数第二位的'1' 结果=1 输出1 否则输出0 int temp = number & mask; printf("%d", temp ? 1 : 0 ); } printf("\n"); } /* 位段, 常用于单片机特殊寄存器结构,编译器会安排其中位的排列,不可移植性 当所需要的位超过一个int(32位)时,使用多个int,直到容纳这个“位段” 可以用位段的成员名称访问指定数据的第几位,比移位,与,或更直观让人接受 */ //位段结构体 struct U0 { unsigned int leading : 3; unsigned int flag1 : 1; unsigned int flag2 : 1; int trailing : 27; }; void testU0(){ struct U0 uu; uu.leading = 2; uu.flag1 = 1; uu.flag2 = 1; uu.trailing = 0; printf("sizeof(uu)==%lu\n", sizeof(uu)); int res = *(int*)&uu ; // 取结构体地址,强转成 int指针,获取它的整形值,单片机常用 test_mybitprintf(res); //binary===>00000000000000000000000000011010 } int main() { //test_bit_with_and(); //test_bit_with_or(); //test_bit_with_xor(); //test_mybitprintf(2); testU0(); return 0; }
自定义容器——可变数组
头文件
#ifndef __ARRAY_H__ #define __ARRAY_H__ typedef struct { int *array; int size; }Array; Array array_create(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 __ARRAY_H__
可变数组实现
#define _CRT_SECURE_NO_WARNINGS #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include "array.h" //typedef struct //{ // int *array; // int size; //}Array; const BLOCK_SIZE = 20; //初始化数组大小 Array array_create(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; } //返回数组的大小,封装的概念,保护size不被直接访问, int array_size(const Array *a) { return a->size; } //获取结构的数组指定位置的指针 //返回指针而不是int的意义: 指针既可以获取值,也可以重新赋值, int* array_at(Array *a, int index) { if (index >= a->size) { array_inflate(a, ((index / BLOCK_SIZE + 1) *BLOCK_SIZE ) - a->size); } return &(a->array[index]); } //对数组进行扩容 void array_inflate(Array *a, int more_size) { printf("扩容前的大小=%d\n", a->size); int *p = (char*)malloc(sizeof(int)* (a->size + more_size)); int i = 0; /*for (; i < a->size; i++) { p[i] = a->array[i]; }*/ memcpy(p,a->array); free(a->array); a->array = p; a->size += more_size; printf("扩容后的大小=%d\n", a->size); } int main() { //可变数组的缺陷:拷贝数据的时间,内存受限的情况下,当size超过一半的内存大小时,无法继续申请内存 // 如 内存 16k, 当前array大小 已经达到8k ,剩余8k内存,然而申请 8K + block_size 大小内存时,系统内存不够用 Array a = array_create(1); printf("接受的a的地址==>%x\n", &a); *array_at(&a,3) = 10; printf("%d\n", *array_at(&a, 3)); int number = 0; int cnt = 0; while (number != -1) { scanf("%d", &number); if (number != -1) { *(array_at(&a, cnt++)) = number; } } array_free(&a); return 0; }
自定义链表简单实现
#include <stdio.h> #include <stdlib.h> #include "node.h" //typedef struct _node { // int value; // struct _node *next; //}Node; typedef struct _list{ Node *head ; Node *tail; }List; void add(List *list, int number); void list_print(List *list); int list_remove(List *list, int number); int list_clear(List *list); int main() { /* int number; do { scanf("输入一个整数%d", &number); if (number != -1) { add(&list, number); } } while (number != -1);*/ List list; list.head = NULL; int len = 8; int arr[] = { 1,2,3,4,5,6,7,8}; int i; for ( i = 0; i < len; i++) { printf("第%d次\n",i); add(&list, arr[i]); } list_print(&list); list_remove(&list, 1); List list1; list1.head = NULL; int res = list_remove(&list, 1); if (res > 0) { printf("删除成功\n"); } list_clear(&list); list_print(&list); printf("Hello World! linked-list\n"); return 0; } //清除所有的链表 int list_clear(List *list) { Node *p; Node *q; for (p = list->head; p; p = q) { q = p->next; free(p); } printf("clear ...list size==>%d\n", sizeof(&list)); //list->head = NULL; } //移除链表中某一个数据 int list_remove(List *list, int number) { //问题1.数据是否存在 //问题2.边界处理?数据是在第一个 Node* p; Node* pTemp; int res = -1; if (list->head) { for (pTemp = NULL, p = list->head; p; pTemp = p, p = p->next) { if (number == p->value) { if (pTemp) { pTemp->next = p->next; } else { list->head = p->next; } free(p); res = 1; break; } } } return res; } //输出链表中所有的数据 void list_print(List *list) { Node *p ; if (list->head) { printf("the list is null...\n"); return; } for (p = list->head; p; p = p->next) { printf("-%d", p->value); } printf("\n"); } //将一个数据添加到列表当中 void add(List* pList,int number) { Node *p = (Node*)malloc(sizeof(Node)); p->value = number; p->next = NULL; Node* last = pList->head; if (last) { while (last->next) { last = last->next; } last->next = p; } else { pList->head = p; } }