10.補碼+位運算符+NULL+鏈表

【補碼】
				在vc++6.0中一個int類型的變量所能存儲的數字的範圍是多少
				最小負數的二進制代碼是多少
				最大正數的二進制代碼是多少
				已知一個整數的二級制代碼求出原始的數字
				數字超過最大正數會怎樣

				原碼
					也叫 符號-絕對值碼
					最高位0表示正 1表示負,其餘二進制位是該數字的絕對值的二進制位

					原碼簡單易懂
					加減運算複雜
					存在加減乘除四種運算,增加了CPU的複雜度
					零的表示不唯一

				反碼
					反碼運算不便,也沒有在計算機中應用
				移碼
					表示數值平移N位,N稱爲移碼量
					移碼主要用於浮點數的階碼的存儲
				補碼
					已知十進制轉二進制
						求正整數轉二進制
							除2取餘,直至商爲零,餘數倒序排序
						求負整數轉二進制
							先求與該負數相對應的正整數的二進制代碼,然後將
							所有位取反,末尾加1,不夠所屬變量類型字節數的位數時,左邊補1
							舉例:int -3
								先求3的的二進制碼爲 011
								取反爲	100
								末尾加1爲 101
								因爲是整型變量爲4個字節數,即4X8=32位,而上面只佔了3位,所以左邊需要補29個零
								最終爲:11111111111111111111111111111101
						求零的二進制
							全是零

					已知二進制求十進制
						如果首位是0,則表明是正整數,按普通方法來求
						如果首位是1,則表明是負整數,將所有位取反,末尾加1,所得數字就是該負數的絕對值
						如果全是零,則對應的十進制數字就是零
			進制轉化
				進制即時逢幾進一
				比如,N進制就是逢N進一
				計算機只識別二進制
				而人們常用的習慣使用的是十進制
				----------------------------------------
				在數字後面加B表示二進制
							O表示八進制
							D表示十進制
							H表示十六進制
【位運算符】
			&   按位與
					&& 邏輯與 也叫並且
					&&與& 的含義完全不同
					1&1 = 1
					1&0 = 0
					0&0 = 0
					0&1 = 0

			|	
				||邏輯或
				| 按位或	
					1|1 = 1
					1|0 = 1
					0|0 = 0
					0|1 = 1
			~	
				按位取反
				~i就是把i變量所有的二進制位取反

			^
				按位異或
				相同爲零,不同爲1
				1 ^ 0 = 1
				0 ^ 1 = 1
				1 ^ 1 = 0
				0 ^ 0 = 0

			<<
				按位左移
				i >> 3 表示把i的所有二進制位左移3位,右邊補零

				左移n位相當於乘以2的n次方

				面試題:
					A) i = i*8;
					B) i = i << 3;
					請問上述兩個語句,哪個語句執行的速度快
					答案:B快
					因爲如果是乘法,在計算機中運算的時候會需要調用到很多複雜的東西,
					而位移卻是不用,所以位移執行快。i << 3 = i * 2^3 (i乘以2的3次方)
			>>
				按位右移
				i >> 3 表示把i的所有二進制位右移3位,左邊一般是0,也可能根據最高位是1或者0

				右移n位相當於除以2的n次方,前提是不能溢出,數據不能移的丟失了
				
				面試題:
					A) i = i/8;
					B) i = i >> 3;
					請問上述兩個語句,哪個語句執行的速度快
					答案:B快

			位運算的現實意義:
				通過位運算符我們可以對數據的操作精確到每一位
			-------------------------------------------------------------
			#include <stdio.h>
			int main(void)
			{
				int i = 5;
				int j = 7;
				int k;

				k = i & j;     //表示按位與
				printf("%d\n",k);    //這裏的結果是5
				k = i && j;        //K的值只能是1或者0,因爲&&是個邏輯運算符,
								//邏輯運算符的結果只能是真或假,真用1表示,假用0表示	   
				printf("%d\n",k);   //這裏的結果是1
				return 0;
			}
			解析:
			5的二進制碼爲:0101
			7的二進制碼爲:0111
			兩個二進制碼進行與運算的結果爲:0101
			所以第一個printf的結果是5
			----------------------------------------------------------------------------
			#include <stdio.h>
			int main(void)
			{
				int i = 3;
				int j = 5;
				int k;

				k = i|j;
				printf("%d\n",k);

				k = ~i;   //
				printf("%d\n",k);  //k的值爲4

				k = i << i;
				printf("%d\n",k);  //k的值爲6
				return 0;
			}
			3的二進制碼爲:0011
			5的二進制碼爲:0101
			兩個二進制碼進行或運算的結果爲:0111 即爲7
			最終k的值爲7
			----------------------------------------------------------------
【NULL】
			C語言中二進制全部爲零的含義:
			1.數值零
			2.字符串結束標記符‘\0’
			3.空指針NULL
				NULL表示的是零,而這個零不代表數字零,而表示的是內存單元的編號零.

			根據解碼的不同而結果不同

			計算機規定了,以零爲編號的存儲單元的內容不可讀,不可寫
			--------------------------------------------------------

【鏈表】
		算法:
			通俗的定義:
				解題的方法和步驟
			狹義的定義:
				對存儲數據的操作
				對不同的存儲結果,要完成某一個功能所執行的操作是不一樣的
				比如:
					要輸出數組中所有的元素的操作和
					要輸出鏈表中所有的元素的操作肯定是不一樣的
				這說明:
					算法是依附於存儲結構的
					不同的存儲結構,所執行的算法是不一樣的
			廣義的定義:
				廣義的算法也叫泛型
				無論數據是如何存儲的,對數據的操作都是一樣的

		至少可以通過兩種結構來存儲數據:
			數組
				缺點:
					需要一個連續的很大的內存
					插入和刪除元素的效率很低
				優點:
					存取速度快
			鏈表
				專業術語;
					首節點
						存放第一個有效數據的節點
					尾節點
						存放最後一個有效數據的節點
					頭結點
						頭結點的數據類型和首節點的類型是一模一樣的
						頭結點是首節點前面的那個節點
						頭結點並不存放有效數據
						設置頭結點的目的是爲了方便對鏈表的操作
					頭指針
						存放頭結點地址的指針變量

					確定一個鏈表需要一個參數
						頭指針

				優點:
					插入刪除元素效率高
					不需要一個連續的很大的內存
				缺點:
					查找某個位置的元素效率低
				-----------------------------------------------------------------------------
				#include <stdio.h>
				#include <malloc.h>
				#include <stdlib.h>
				struct Node
				{
				        int data;  //數據域
				        struct Node *pNext;  //指針域
				};

				struct Node *create_list(void);  //函數聲明
				#include <stdio.h>
				#include <malloc.h>
				#include <stdlib.h>
				struct Node
				{
				        int data;  //數據域
				        struct Node *pNext;  //指針域
				};

				struct Node *create_list(void);  //函數聲明
				void traverser_list(struct Node *);
				int main(void)
				{
				        struct Node *pHead = NULL;
				        pHead = create_list(); //創建一個非循環單鏈表,且將鏈表頭結點地址賦給pHead
				                                //然後主函數就可以通過pHead確定這個新建鏈表
				        traverser_list(pHead); //輸出鏈表中的每個元素   

				        return 0;
				}

				struct Node *create_list(void)
				{
				        int len;    //用來存放有效節點的個數
				        int i;
				        int val;  //用來臨時存放用戶輸入的節點的值

				        struct Node *pHead = (struct Node *)malloc(sizeof(struct Node));
				        if (NULL == pHead)
				        {
				                printf("分配失敗,程序終止!\n");
				                exit(-1);
				        }
				        struct Node *pTail = pHead;
				        pTail->pNext = NULL;  //等價於(*pTail).pNext
				        
				        printf("請輸入您需要生成的鏈表節點的個數:len = ");
				        scanf("%d",&len);
				        
				        for(i=0;i<len;++i)
				        {
				                printf("請輸入第%d個節點的值:",i+1);
				                scanf("%d",&val);
				                
				                struct Node *pNew = (struct Node *)malloc(sizeof(struct Node));
				                if(NULL == pNew)
				                {
				                        printf("分配失敗,程序終止!\n");
				                        exit(-1);
				                }
				                pNew->data = val;
				                pTail->pNext = pNew;
				                pNew->pNext = NULL;
				                pTail = pNew;
				        }
				        return pHead;
				}

				bool empty_list(struct Node *pHead)
				{
				        if(pHead->pNext == NULL;)
				                return true;
				        else
				                return false;
				}
				void traverser_list(struct Node *pHead)
				{
				        struct Node *p = pHead->pNext;
				        while(NULL != p)
				        {
				                printf("%d\n",p->data);
				                p = p->pNext;
				        }
				        return;
				}
				-------------------------------------------------------------------------------------

發佈了113 篇原創文章 · 獲贊 119 · 訪問量 50萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章