網站首頁 編程語言 正文
一、數據類型
數據類型有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
相關推薦
- 2022-08-12 C#實現簡單的字符串加密_C#教程
- 2022-03-15 跨域報錯:Response to preflight request doesn‘t pass ac
- 2022-07-20 如何go語言比較兩個對象是否深度相同_Golang
- 2022-08-12 Windows?Server?修改遠程桌面端口的實現_win服務器
- 2022-05-07 LINQ教程之LINQ操作語法_實用技巧
- 2022-05-11 如果解決tomcat端口號被占用
- 2022-07-19 C++分別使用std::chrono和clock()計算時間間隔
- 2022-08-05 C#實現圖形界面的時鐘_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支