国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C/C++ - 一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

2021-12-15 14:24風(fēng)繼續(xù)吹TT C/C++

這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)的存儲(chǔ)和取出詳細(xì)講解,作者使用圖文代碼實(shí)例講解,有感興趣的同學(xué)可以學(xué)習(xí)研究下,希望能給你帶來(lái)幫助

前言

前面我們學(xué)習(xí)了C語(yǔ)言的一些基本知識(shí)和基礎(chǔ)的語(yǔ)法,想必大家對(duì)C語(yǔ)言都有了自己的認(rèn)識(shí)。

當(dāng)然只是學(xué)習(xí)這些知識(shí)還是不夠的,我們需要進(jìn)行更加深入的學(xué)習(xí)。

從本章開始,我們將進(jìn)行C語(yǔ)言進(jìn)階階段的學(xué)習(xí),所以難度會(huì)有所增加。

 

數(shù)據(jù)類型介紹

前面我們已經(jīng)學(xué)習(xí)了基本的內(nèi)置類型:

char //字符數(shù)據(jù)類型
short //短整型
int //整形
long //長(zhǎng)整型
long long //更長(zhǎng)的整形
float //單精度浮點(diǎn)數(shù)
double //雙精度浮點(diǎn)數(shù)

//C語(yǔ)言有沒有字符串類型?

C語(yǔ)言中沒有字符串類型,但是C語(yǔ)言提供了字符串常量。

C語(yǔ)言中字符串的概念:以 NULL('\0') 字節(jié)結(jié)尾的零個(gè)或多個(gè)字符,字符串通常儲(chǔ)存在字符數(shù)組中

當(dāng)一個(gè)字符串常量出現(xiàn)在一個(gè)表達(dá)式中時(shí),表達(dá)式所使用的值就是這些字符所存儲(chǔ)的地址,因此可以把字符串常量賦值給一個(gè)“指向字符的指針”。以及他們所占存儲(chǔ)空間的大小。

類型的意義:

1. 使用這個(gè)類型開辟內(nèi)存空間的大小(大小決定了使用范圍)。

2. 如何看待內(nèi)存空間的視角。

int main()
{
	int a = 10;//創(chuàng)建空間后,這塊空間的內(nèi)容以整型的方式考慮和使用
	char c = 'a';//創(chuàng)建空間后,以字符類型的方式考慮和使用
	return 0;
}

 

類型的基本歸類

整形家族:

char
unsigned char
signed char

short
unsigned short [int]
signed short [int]

int
unsigned int
signed int

long
unsigned long [int]
signed long [int]

無(wú)符號(hào)數(shù):即有符號(hào)數(shù)的符號(hào)位表示為有效位。

例如:

#include<stdio.h>
int main()
{
	unsigned int a = -1;
	printf("%u", a);
	return 0;
}

這里的-1是一個(gè)有符號(hào)數(shù),當(dāng)我們以無(wú)符號(hào)數(shù)打印時(shí),最高位不再是符號(hào)位,且無(wú)符號(hào)數(shù)的原反補(bǔ)碼相同,則它的所有位為1,打印出來(lái)是一個(gè)很大的數(shù)。

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

這里我們可以清楚的看出無(wú)符號(hào)與有符號(hào)數(shù)的區(qū)別。

注意:有符號(hào)中的 -128 就表示為 10000000。

并且我們可以推算出有符號(hào)char類型所能表示的范圍是-128――127;無(wú)符號(hào)char類型所能表示的范圍是0――255。同理也可以推算出其他類型的范圍。

 

ps:char類型有無(wú)符號(hào)取決于編譯器的類型 ,short,int,long均表示為有符號(hào),前面加unsigned才表示為無(wú)符號(hào)

浮點(diǎn)數(shù)家族:

float
double

構(gòu)造類型:

> 數(shù)組類型
> 結(jié)構(gòu)體類型 struct
> 枚舉類型 enum
> 聯(lián)合類型 union

所謂數(shù)組類型,即去掉數(shù)組名后剩下的就是數(shù)組的類型。

例如:我們求一個(gè)變量的大小,可以通過它變量名求,也可以通過它的類型求大小。數(shù)組亦是如此。

int main()
{
	int a = 10;
	int arr[10] = { 0 };
	printf("%d\n", sizeof(a));//4
	printf("%d\n", sizeof(int));//4
	printf("%d\n", sizeof(arr));//40
	printf("%d\n", sizeof(int [10]));//40
	return 0;
}

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

指針類型

int *pi;
char *pc;
float* pf;
void* pv;

空類型:

void 表示空類型(無(wú)類型)
通常應(yīng)用于函數(shù)的返回類型、函數(shù)的參數(shù)、指針類型。

void test(void)
{
	printf("hehe\n");
}
int main()
{
	test();
	return 0;
}

 

整形在內(nèi)存中的存儲(chǔ)

我們之前講過一個(gè)變量的創(chuàng)建是要在內(nèi)存中開辟空間的。空間的大小是根據(jù)不同的類型而決定的。
那接下來(lái)我們談?wù)剶?shù)據(jù)在所開辟內(nèi)存中到底是如何存儲(chǔ)的?

比如:

int a = 20;
int b = -10;

我們知道為 a 分配四個(gè)字節(jié)的空間。 那如何存儲(chǔ)?
下來(lái)了解下面的概念:

 

原碼、反碼、補(bǔ)碼

計(jì)算機(jī)中的有符號(hào)數(shù)有三種表示方法,即原碼、反碼和補(bǔ)碼。
三種表示方法均有符號(hào)位和數(shù)值位兩部分,符號(hào)位都是用0表示“正”,用1表示“負(fù)”,而數(shù)值位
三種表示方法各不相同。


原碼
直接將二進(jìn)制按照正負(fù)數(shù)的形式翻譯成二進(jìn)制就可以。

反碼
將原碼的符號(hào)位不變,其他位依次按位取反就可以得到了

補(bǔ)碼
反碼+1就得到補(bǔ)碼。

正數(shù)的原、反、補(bǔ)碼都相同。
對(duì)于整形來(lái)說(shuō):數(shù)據(jù)存放內(nèi)存中其實(shí)存放的是補(bǔ)碼。

為什么呢?

在計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來(lái)表示和存儲(chǔ)。原因在于,使用補(bǔ)碼,可以將符號(hào)位和數(shù)值域統(tǒng)一處理; 同時(shí),加法和減法也可以統(tǒng)一處理(CPU只有加法器)此外,補(bǔ)碼與原碼相互轉(zhuǎn)換,其運(yùn)算過程是相同的,不需要額外的硬件電路

例如:

int main()
{
	int a = -1;
	//10000000000000000000000000000001--原碼
	//11111111111111111111111111111110--反碼(原碼符號(hào)位不變,其他位按位取反)
	//11111111111111111111111111111111--補(bǔ)碼(補(bǔ)碼+1)
	int b = 10;//正整數(shù)原反補(bǔ)相同
	//00000000000000000000000000001010--原碼
	//00000000000000000000000000001010--反碼
	//00000000000000000000000000001010--補(bǔ)碼
	return 0;
}

我們看看在內(nèi)存中的存儲(chǔ):

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

內(nèi)存中是以十六進(jìn)制的形式儲(chǔ)存的,那10應(yīng)該表示為 00 00 00 0a,為什么這里會(huì)倒過來(lái)呢??

 

大小端介紹

什么大端小端:

大端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的高地址中,而數(shù)據(jù)的高位,保存在內(nèi)存的低地址中;

小端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的低地址中,而數(shù)據(jù)的高位,,保存在內(nèi)存的高地址中。

為什么有大端和小端:

為什么會(huì)有大小端模式之分呢?這是因?yàn)樵谟?jì)算機(jī)系統(tǒng)中,我們是以字節(jié)為單位的,每個(gè)地址單元都對(duì)應(yīng)著一個(gè)字節(jié),一個(gè)字節(jié)為8bit。但是在C語(yǔ)言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對(duì)于位數(shù)大于8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個(gè)字節(jié),那么必然存在著一個(gè)如果將多個(gè)字節(jié)安排的問題。因此就導(dǎo)致了大端存儲(chǔ)模式和小端存儲(chǔ)模式。
例如一個(gè) 16bit 的 short 型 x ,在內(nèi)存中的地址為 0x0010 , x 的值為 0x1122 ,那么 0x11 為高字節(jié), 0x22為低字節(jié)。對(duì)于大端模式,就將 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,剛好相反。我們常用的 X86 結(jié)構(gòu)是小端模式,而 KEIL C51 則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來(lái)選擇是大端模式還是小端模式。

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

百度2015年系統(tǒng)工程師筆試題:

請(qǐng)簡(jiǎn)述大端字節(jié)序和小端字節(jié)序的概念,設(shè)計(jì)一個(gè)小程序來(lái)判斷當(dāng)前機(jī)器的字節(jié)序。(10分)

//代碼1
#include <stdio.h>
int check_sys()
{
  int i = 1;
  //char*p = (char*)&i;
  return (*(char*)&i);//先將i的地址取出強(qiáng)制類型轉(zhuǎn)換為char*
                      //解引用后只會(huì)訪問一個(gè)字節(jié),且為最低位的那個(gè)字節(jié)
                      //如果是小端存儲(chǔ)(01 00 00 00)則解引用后得到的是1
                      //如果是大端存儲(chǔ)(00 00 00 01)則解引用后得到的是0
}
int main()
{
  int ret = check_sys();
  if (ret == 1)
  {
      printf("小端\n");
  }
  else
  {
      printf("大端\n");
  }
  return 0;
}
//代碼2
int check_sys()//這里我們后面講到聯(lián)合時(shí)再仔細(xì)講解
{
  union
  {
      int i;
      char c;
  }un;
  un.i = 1;
  return un.c;
}

練習(xí)

1.
//輸出什么?
#include <stdio.h>
int main()
{
  char a= -1;
  signed char b=-1;
  unsigned char c=-1;
  //00000000000000000000000011111111
  printf("a=%d,b=%d,c=%d",a,b,c);
  return 0;
}

a和b毫無(wú)疑問是-1,雖然會(huì)進(jìn)行整形提升,但所有位都是1并不會(huì)影響最后的結(jié)果。

c因?yàn)槭且粋€(gè)無(wú)符號(hào)數(shù),而這里%d是以有符號(hào)數(shù)da印,需要整型提升,所以應(yīng)該是255。

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

下面程序輸出什么?

2.
#include <stdio.h>
int main()
{
  char a = -128;
  //-128的二進(jìn)制位
  //10000000000000000000000010000000
  //11111111111111111111111101111111
  //11111111111111111111111110000000
  // a中存的二進(jìn)制位
  //100000000
  printf("%u\n",a);//以無(wú)符號(hào)整形打印,需進(jìn)行整形提升,左邊補(bǔ)1
                   //11111111111111111111111110000000  4294967168
  return 0;
}
3.
#include <stdio.h>
int main()
{
  char a = 128;
  //char類型的范圍是-128到127,128按照二進(jìn)制位轉(zhuǎn)換其實(shí)就是-128,所以和上面相同
  printf("%u\n",a);
  return 0;
}
4.
int i= -20;
unsigned int j = 10;
//-20
//10000000000000000000000000010100  原碼
//11111111111111111111111111101011  反碼
//11111111111111111111111111101100  補(bǔ)碼
//10
//00000000000000000000000000001010  原反補(bǔ)
//i+j
//11111111111111111111111111110110  補(bǔ)碼
//11111111111111111111111111110101  反碼
//10000000000000000000000000001010  原碼  -10
printf("%d\n", i+j);
//按照補(bǔ)碼的形式進(jìn)行運(yùn)算,最后格式化成為有符號(hào)整數(shù)
5.
unsigned int i;
for(i = 9; i >= 0; i--)//i為無(wú)符號(hào)數(shù)恒大于0,條件恒成立,死循環(huán)
{
  printf("%u\n",i);
}
6.
int main()
{
  char a[1000];
  int i;
  for(i=0; i<1000; i++)
  {
      a[i] = -1-i;//a[0]=-1,且數(shù)組中數(shù)據(jù)類型為char,范圍是-128到127
  }
  printf("%d",strlen(a));//strlen遇到'\0'(0)就停止計(jì)數(shù),而這里數(shù)組的第256個(gè)元素a[255]=0
  return 0;              //所以這里輸出255
}
7.
#include <stdio.h>
unsigned char i = 0;
int main()
{
  for(i = 0;i<=255;i++)//i為無(wú)符號(hào)數(shù)且為char類型,i<=255恒成立,死循環(huán)
  {
      printf("hello world\n");
  }
  return 0;
}

 

浮點(diǎn)型在內(nèi)存中的存儲(chǔ)

常見的浮點(diǎn)數(shù):

3.14159 1E10 浮點(diǎn)數(shù)家族包括: float、double、long double 類型。 浮點(diǎn)數(shù)表示的范圍:float.h中定義。

浮點(diǎn)數(shù)存儲(chǔ)的例子:

int main()
{
  int n = 9;
  float *pFloat = (float *)&n;
  printf("n的值為:%d\n",n);
  printf("*pFloat的值為:%f\n",*pFloat);
  *pFloat = 9.0;
  printf("num的值為:%d\n",n);
  printf("*pFloat的值為:%f\n",*pFloat);
  return 0;
} 

輸出的結(jié)果是什么呢?

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

num 和 *pFloat 在內(nèi)存中明明是同一個(gè)數(shù),為什么浮點(diǎn)數(shù)和整數(shù)的解讀結(jié)果會(huì)差別這么大? 要理解這個(gè)結(jié)果,一定要搞懂浮點(diǎn)數(shù)在計(jì)算機(jī)內(nèi)部的表示方法。

根據(jù)國(guó)際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會(huì)) 754,任意一個(gè)二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:

  • (-1)^S * M * 2^E
  • (-1)^s表示符號(hào)位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù)。
  • M表示有效數(shù)字,大于等于1,小于2。
  • 2^E表示指數(shù)位。

舉例來(lái)說(shuō):

十進(jìn)制的5.0,寫成二進(jìn)制是 101.0 ,相當(dāng)于 1.01×2^2 。 那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。

十進(jìn)制的-5.0,寫成二進(jìn)制是 -101.0 ,相當(dāng)于 -1.01×2^2 。那么,s=1,M=1.01,E=2

注意:有些數(shù)字可能不能精確表示,例如0.3

IEEE 754規(guī)定: 對(duì)于32位的浮點(diǎn)數(shù),最高的1位是符號(hào)位s,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

對(duì)于64位的浮點(diǎn)數(shù),最高的1位是符號(hào)位S,接著的11位是指數(shù)E,剩下的52位為有效數(shù)字M。

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

IEEE 754對(duì)有效數(shù)字M和指數(shù)E,還有一些特別規(guī)定。 前面說(shuō)過, 1≤M<2 ,也就是說(shuō),M可以寫成 1.xxxxxx 的形式,其中xxxxxx表示小數(shù)部分。

IEEE 754規(guī)定,在計(jì)算機(jī)內(nèi)部保存M時(shí),默認(rèn)這個(gè)數(shù)的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的時(shí)候,只保存01,等到讀取的時(shí)候,再把第一位的1加上去。這樣做的目的,是節(jié)省1位有效數(shù)字。以32位浮點(diǎn)數(shù)為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數(shù)字。

至于指數(shù)E,情況就比較復(fù)雜。

首先,E為一個(gè)無(wú)符號(hào)整數(shù)(unsigned int) 這意味著,如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。但是,我們知道,科學(xué)計(jì)數(shù)法中的E是可以出現(xiàn)負(fù)數(shù)的,所以IEEE 754規(guī)定,存入內(nèi)存時(shí)E的真實(shí)值必須再加上一個(gè)中間數(shù),對(duì)于8位的E,這個(gè)中間數(shù)是127;對(duì)于11位的E,這個(gè)中間數(shù)是1023。比如,2^10的E是10,所以保存成32位浮點(diǎn)數(shù)時(shí),必須保存成10+127=137,即10001001。

例如:

int main()
{
	float f = 5.5f;
	//101.1
	//科學(xué)計(jì)數(shù)法:(-1)^0*1.011*2^2
	//S=0
	//M=1.011
	//E=2  +127存儲(chǔ)
	//二進(jìn)制表示:0 10000001 01100000000000000000000
	//十六進(jìn)制:  40 B0 00 00
	return 0;
}

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

其中我們可以看出浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ),也是有大小端的。

然后,指數(shù)E從內(nèi)存中取出還可以再分成三種情況:

E不全為0或不全為1

這時(shí),浮點(diǎn)數(shù)就采用下面的規(guī)則表示,即指數(shù)E的計(jì)算值減去127(或1023),得到真實(shí)值,再將有效數(shù)字M前加上第一位的1。 比如: 0.5(1/2)的二進(jìn)制形式為0.1,由于規(guī)定正數(shù)部分必須為1,即將小數(shù)點(diǎn)右移1位,則為1.0*2^(-1),其階碼為-1+127=126,表示為01111110,而尾數(shù)1.0去掉整數(shù)部分為0,補(bǔ)齊0到23位00000000000000000000000,則其二進(jìn)制表示形式為:

0 01111110 00000000000000000000000

E全為0

這時(shí),浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023)即為真實(shí)值, 有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0,以及接近于0的很小的數(shù)字。

E全為1

這時(shí),如果有效數(shù)字M全為0,表示±無(wú)窮大(正負(fù)取決于符號(hào)位s);

最后來(lái)解釋一下前面的題:

int main()
{
  int n = 9;
  //000000000000000000000000000001001
  float* pFloat = (float*)&n;
  //將整形9的二進(jìn)制位轉(zhuǎn)化為浮點(diǎn)型,S=0,E為全0,所以可以表示近似為0
  printf("n的值為:%d\n", n);
  printf("*pFloat的值為:%f\n", *pFloat);
  *pFloat = 9.0;
  //1001.0
  //S=0,E=130(3+127),M=1001
  //9.0在內(nèi)存中的二進(jìn)制:01000001000100000000000000000000
  printf("num的值為:%d\n", n);//這里打印的n是以9.0在內(nèi)存中的二進(jìn)制位以整形打印,所以結(jié)果不是9.0
  printf("*pFloat的值為:%f\n", *pFloat);
  return 0;
}

一篇文章帶你了解C語(yǔ)言--數(shù)據(jù)的儲(chǔ)存

總結(jié)

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/Edward_Asia/article/details/119645045

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 精品久久久一区 | 免费的av网站| 最新中文字幕视频 | 日韩在线观看中文字幕 | 超碰日韩 | h小视频在线| 国产高清视频一区 | 欧美a视频 | 国产日韩免费视频 | 在线一区观看 | 欧美一区二区在线播放 | 丝袜美腿一区二区三区 | 国产精品久久久久久久久久新婚 | 欧美在线视频一区 | 日韩一区二区视频在线 | 91精品国产综合久久久久久丝袜 | 亚洲精品在线视频 | 亚洲一区在线视频 | 欧美一级淫片007 | 污视频网站在线观看 | 久久久精品国产一区 | 中文视频在线 | av国产精品| www久久精品 | 九九热在线视频观看这里只有精品 | 国产精品一二三区 | 亚洲免费视频观看 | 免费看黄在线 | 欧美区国产 | 午夜看片网站 | 国产毛片18片毛一级特黄日韩a | 久久99精品久久久久久琪琪 | 亚洲视频自拍 | 久久久久久久久久久免费 | 国产精品成人在线观看 | 国产目拍亚洲精品99久久精品 | 美女超碰| 精品亚洲一区二区 | 久久日韩 | 最好观看的2018中文 | 北条麻妃在线一区二区免费播放 |