日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++淺析數據在內存中如何存儲_C 語言

作者:7昂7. ? 更新時間: 2022-10-05 編程語言

一、數據類型

數據類型有7種:

? ?char? ? ? ? ? ? 字符型 ?
? ?short? ? ? ? ? 短整型?
? ?int? ? ? ? ? ? ? ?整型
? ?long? ? ? ? ? ? 長整型
? ?long long? ? 更長整型
? ?float? ? ? ? ? ? 單精度浮點數?
? ?double? ? ? ? 雙精度浮點數

二、原碼反碼補碼

計算機中的整數有三種2進制表示方法,即原碼、反碼和補碼。

三種表示方法均有符號位和數值位兩部分,符號位都是用0表示’正”,用1表示"負”,而數值位正數的原、反、補碼都相同。

負整數的三種表示方法各不相同.

原碼:是直接將數值按照正負數的形式翻譯成二進制得到原碼。

反碼:原碼的符號位不變,其他位依次按位取反得到反碼。

補碼:反碼加1,得到補碼。

計算例子:如圖

計算a+b:

a是正數,原碼等于補碼:00000000 00000000 00000000 00000111

b是負數,原碼:10000000 00000000 00000000 00001010

反碼:111111111 11111111 11111111 11110101

補碼:11111111 11111111 11111111 11110110

a+b的補碼分別相加得到:11111111 11111111 11111111 11111101

而打印的是%d即有符號整型,要把它轉化為原碼,減一取反的到原碼:

10000000 00000000 00000000 00000011 再化為10進制就是-3

看下運行結果:

三、大小端

數據在內存中有兩種存儲方式一個是大端模式一個是小端模式。

在計算機系統中,以字節為單位的,每個地址單元對應著一個字節,一個字節為8bit。但在C語言中除了8 bit的char之外,還有16 bit的short型,32bit的long型(要看具體的編譯器),另外,對于位數大于8位的處理器,例如16位或者32位的處理器,由于奇存器寬度大于一個字節,那么心然存在著一個如何將多個字節安排的問題。這導致了大端存儲模式和小端存儲模式。

我們如何判斷當前機器的字節順序:

#include<stdio.h>
int is_sys()
{
	int a = 1;
	return (*(char *)&a);
}
int main()
{
	int ret = is_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

取一個整型數1,補碼:0000000 0000000 00000000 00000001,要判斷它哪種存儲模式,只需要拿出第一個字節,因為低位放在高地址處時是大端,低位放在低地址處時小端,取地址先轉化為字符型指針保證拿出一個字節 ,再解引用取出內容,如果是1就是小端,反之是大端。

整型提升

C的整型算術運算總是至少以缺省整型類型的精度來進行的。為了獲得這個精度,表達式中的字符和短整型操作數在使用之前被轉換為普通整型,這種轉換稱為整型。

我們用字符類型存儲數據會發生截斷,因為一個數是四個字節,字符型只能存儲一個字節,截斷之后看當前符號位:

對于有符號類型,如果是1就把1之前的位補全1進行整型提升,如果是0就把0之前的位補全0進行整型提升。

對于無符號類型,直接補全0.

(1)我們看如下例子就能很好理解:

#include<stdio.h>
int main()
{
	char a = -2;
	unsigned char b = -10;
	printf("%d %d", a,b);
}

a=-2,原碼:10000000 0000000 00000000 00000010

反碼: 11111111 11111111 11111111 11111101

補碼: 11111111 11111111 11111111 11111110

但是a是字符型只能存一個字節,會發生截斷只取低位的一個字節即:11111110

而我們打印的是有符號整型%d,會發生整型提升,因為它是負的,所以在前面補1

11111111 11111111 11111111 11111110,而打印的是原碼,所以再轉換為原碼。減一取反:10000000 00000000 00000000 00000010 結果是-2

b=-10,原碼:10000000 00000000 00000000 00001010

反碼: 11111111 11111111 11111111 11110101

補碼 :11111111 11111111 11111111 11110110

同上截斷之后:11110110 因為他是無符號整型在前面補0:

00000000 00000000 00000000 11110110.直接是原碼打印結果是246.

再驗證下結果:

(2)另外%u是打印無符號整型。也是被截斷之后看原來的數是否有符號,如果有符號不補1或補0,無符號直接補0.然后補完之后直接當做原碼打印

例如 char=-128

原碼:10000000 00000000 00000000 10000000

反碼: 11111111 11111111 11111111 01111111

補碼: 11111111 11111111 11111111 10000000

因為是字符型拿低位的一個字節 1000000,又因為他是負數補1:

11111111 11111111 11111111 10000000,直接當原碼打印 因數太大直接看結果:

(3)再來分析一個:

#include<stdio.h>
int main()
{
	int i = -20;
	unsigned char j = 10;
	unsigned char b = i + j;
	printf("%u", b);
}

i的原碼:10000000 00000000 00000000 00010100;

反碼: 11111111 1111111 11111111 11101011

補碼: 11111111 11111111 11111111 11101100

而j是無整形且字符型值 因為它是正數,原碼等于補碼:

00000000 00000000 00000000 00001010

兩者相加是:11111111 11111111 11111111 11110110

而又存在一個無符號字符型,發生截斷:11110110

而打印的是%u直接整型提升補0 補碼等于原碼 :

00000000 00000000 00000000 11110110結果是246

看結果:

原文鏈接:https://blog.csdn.net/m0_59292239/article/details/126253968

欄目分類
最近更新