字符串的定義方式及輸出:
#include <stdio.h>
#include <stdlib.h>
void strPrint(char* data,int size)
{int i;for(i=0;i<size;i++){printf("函數打印數組:%c\n",*data++);}putchar('\n');
}
int main()
{int i=0;int a[3]={1,2,3};char c='a';//第一種方式:char str[5]={'a','b','c','d','e'};//定義字符串并進行初始化,類比于整數數組很土strPrint(str,sizeof(str)/sizeof(str[0]));//第二種方式:char str2[5]="fghij";//寫在一起的時候就不用大括號了strPrint(str2,sizeof(str2)/sizeof(str2[0]));//第三種方式//char str3[]={'k','l','m'};char str3[]="klm";//數組大小不寫,但會根據元素個數默認分配//sizeof計算時會大一個字節,因為將字符串的結束標志\0,算入了strPrint(str3,sizeof(str3)/sizeof(str3[0])-1);//第四種方式:指針方式,操作不當,內存非法,會造成段錯誤(sigment error)char* pstr="hello world!";//字符串的最好的定義方式,pstr可以理解為數組的地址(大多數情況下,數組名就是地址)。printf("%s\n",pstr);//字符串用占位符%s表示,不需要用i的下標遍歷system("pause");return 0;
}
字符串在內存中的存儲方式:
#include <stdio.h>
#include <stdlib.h>
//字符存儲方式:字符串在內存中,除了有效字符外,還會自動在后面補一個\0作為字符串結束的標志
//真正計算有效字符的長度用strlen
int main()
{int a[]={1,2,3};//連續的空間,整個數組的的大小是元素個數*元素類型的大小printf("a數組的大小是:%d\n",sizeof(a));printf("a數組一項元素的大小是:%d\n",sizeof(a[0]));printf("a數組的個數是:%d\n",sizeof(a)/sizeof(a[0]));putchar('\n');//字符串的存儲方式char c[]={'a','b','c'};printf("c數組的大小是:%d\n",sizeof(c));printf("c數組一項元素的大小是:%d\n",sizeof(c[0]));printf("c數組的個數是:%d\n",sizeof(c)/sizeof(c[0]));putchar('\n');char e[3]="abc";printf("e數組的大小是:%d\n",sizeof(e));printf("e數組一項元素的大小是:%d\n",sizeof(e[0]));printf("e數組的個數是:%d\n",sizeof(e)/sizeof(e[0]));putchar('\n');//在定義的時候不寫元素個數,數組會在初始化的時候根據元素個數確定數組的大小char d[]="abc";//這種方式計算的數組大小會偏大一個字節,因為有字符串結束的標志\0printf("d數組的大小是:%d\n",sizeof(d));printf("d數組一項元素的大小是:%d\n",sizeof(d[0]));printf("d數組的個數是:%d\n",sizeof(d)/sizeof(d[0]));//printf("d[3]:%c",d[3]);//第三格元素是\0打印不出來putchar('\n');//利用while循環輸出int i=0;while(d[i]!='\0'){printf("while循環打印:%c",d[i]);i++;putchar('\n');}char k='a';printf("字符的大小是:%d\n",sizeof(k));system("pause");return 0;
}
sizeof和strlen區別:
#include <stdio.h>
#include <stdlib.h>
/*
計算字符串中字符的個數不能用sizeof來計算字符串中有效字符的個數!!!!應該要用strlen(),strlen()在計算字符串大小的時候,遇到\0后就結束計數比如:strlen(hello\0world)=5而sizeof(hello\0w)=8*/
int main()
{int a[]={1,2,3};printf("數組a的元素個數:%d\n",sizeof(a)/sizeof(a[0]));char a2[]="hello";printf("數組a2元素個數:%d\n",sizeof(a2)/sizeof(a2[0]));//輸出6printf("strlen輸出:%d\n",strlen(a2));char a3[128]="hello";//其他123個是\0printf("數組a3元素個數:%d\n",sizeof(a3)/sizeof(a3[0]));//輸出128printf("strlen輸出:%d\n",strlen(a3));system("pause");return 0;
}
字符串操作常用的API:
API是函數調用的接口,通俗來講就是函數。
這個是我對上面第四種方式定義字符串的理解:
#include <stdio.h>
#include <stdlib.h>
//puts()函數,printf(); 在輸出數據的時候,遇到 ‘\0’ 就會結束輸出。
/*數組名本身就是地址,指針數組的數組名作為地址又存放指針
用法和二級指針相似但是不是二級指針,sizeof(數組名)和sizeof(指針)不一樣*/
int main()
{char* a1[]={"hello","world"};//ai[0]=hello,a1[1]=world,hello和world都是指針//hello在這里是指針,作為數組中的元素printf("a1的大小是:%d\n",sizeof(a1));//這里輸出8,因為數組中有兩個指針,在啊哈C這個編譯器下指針大小為4個字節printf("a1輸出:%p\n",a1);//輸出的是指針數組的地址,也是第一個指針的地址printf("a1輸出:%p\n",&a1[0]);//**a1++;//a1是常量不能++printf("a1輸出:%s\n",*a1);//輸出的是hello,因為a1既是數組名又是第一個指針的地址,*a1就是指針本身就是hello,%s可以輸出指針printf("a1輸出:%c\n",**a1);//輸出的是h因為*a1是hello,可以把hello當做數組,所以**a1就是去第一個元素的內容為h。printf("a1輸出:%c\n",(*a1)[0]);//等同于**a1,把hello當做數組,把*a1當做數組名,只是當做而已printf("a1輸出:%c\n",(*a1)[1]);//取hello這個數組的第二個元素char* a2="hello";printf("a2輸出:%s\n",a2);//a2是指針用%s可以直接輸出指針對應的字符串printf("a2輸出:%c\n",*a2);//把指針a2看做數組名,*a2就是第一個元素的地址,所以*a2就是hprintf("a2輸出:%c\n",a2[1]);//把指針a2看做數組名,所以輸出eprintf("a2輸出:%c\n",*(a2+2));//將指針向后偏移一位后取內容就是lprintf("a2輸出:%p\n",&a2[0]);//這是第一個元素的地址printf("a2輸出:%p\n",a2);//這個是指針,看成數組的話就是第一個元素的地址和&a2[0]輸出結果一樣/*int* a3[]={1,2,3};//1,2,3在這里是指針,但是不能那么用,容易造非法內存訪問*/system("pause");return 0;
}
puts、gets、memset
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//puts()會自動在輸出后加\n
//而printf()需要手動輸入
//gets()獲取一個字符串
//getchar()和putchar()操作對象是字符
int main()
{char* str="哈嘍!";printf("%s\n",str);puts(str);//char pstr[128]={'\0'};//1、申請空間2、初始化,把每一個元素都初始化為\0char* str2;//野指針 造成非法內存訪問 會出現段錯誤str2=NULL;str2=(char*)malloc(3);//申請空間if(str2==NULL){printf("申請失敗\n");exit(-1);//exit表示退出這個進程,-1表示異常退出 }memset(str2,'\0',3);//初始化,將每個元素初始化為\0/*memset第一個參數是:你要初始化的對象(空間)第二個參數是初始化成什么第三個參數是初始化多大*//* 一旦用了malloc就要注意內存泄露的問題,malloc可能會失敗,要對返回值做判斷,若開辟的內存==NULL,表示開辟失敗*/printf("請輸入字符串:\n");//scanf("%s",str2);gets(str2);puts(str2);system("pause");return 0;
}
strcpy、strncpy、strcmp、strcat
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//漢字所占字節:這和編碼有關,UTF8一個漢字占3個字節,GBK一個漢字占2個字節。
/*
strcpy:字符串復制函數
函數原型是:char *strcpy(char* dest, const char *src);
功能:把從src地址開始且含有NULL結束符的字符串復制到以dest開始的地址空間
說明:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。strncpy:函數用于將指定長度的字符串復制到字符數組中
函數原型:char *strncpy(char *destinin, char *source, int maxlen);
destinin:表示復制的目標字符數組;
source:表示復制的源字符數組;
maxlen:表示復制的字符串長度。
source串長度<=destin串長度(這里的串長度包含串尾NULL字符)
①如果n<source由于長度達到source NULL,正常復制,
如果source中有NULL,strncpy復制到NULL即使沒到n也提前停止,
注意n的選擇當n > destin串長度,destin棧空間溢出產生崩潰異常。
②source串長度>destin串長度
如果n =destin串長度,則destin串沒有NULL字符,會導致輸出會有亂碼。
如果不考慮source串復制完整性,可以將destin 最后一字符置為'\0'。strcat:將兩個char類型連接。
注意:d和s所指內存區域不可以重疊且d必須有足夠的空間來容納s的字符串。
拼接后兩個字符串之間無空格,返回指向d的指針。
函數原型:extern char *strcat(char *dest, const char *src);*//*
字符串比較函數:strcmp()
函數原型:extern int strcmp(const char *s1,const char *s2);
兩個字符串自左向右逐個字符相比(按ASCII值大小相比較),直到出現不同的字符或遇'\0'為止。特別注意:strcmp(const char *s1,const char * s2)這里面只能比較字符串,
即可用于比較兩個字符串常量,或比較數組和字符串常量,不能比較數字等其他形式的參數。
用于比較兩個字符串長度并根據比較結果返回整數。
基本形式為strcmp(str1,str2),若str1=str2,則返回零;
若str1<str2,則返回負數;若str1>str2,則返回正數。
當兩個字符串不相等時,C標準沒有規定返回值會是1 或 -1,只規定了正數和負數。
有些會把兩個字符的ASCII碼之差作為比較結果由函數值返回。但無論如何不能以此條依據作為程序中的流程邏輯。
*//*那什么操作會引起段錯誤呢?1、往受到系統保護的內存地址寫數據,有些內存是內核占用的或者是其他程序正在使用,為了保證系統正常工作,所以會受到系統的保護,而不能任意訪問。2、內存越界(數組越界,變量類型不一致等)3、其他例如:<1>定義了指針后記得初始化,在使用的時候記得判斷是否為NULL<2>在使用數組的時候是否被初始化,數組下標是否越界,數組元素是否存在等<3>在變量處理的時候變量的格式控制是否合理等內存泄漏:內存泄露 memory leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。最終的結果就是導致OOM。內存泄漏是指你向系統申請分配內存進行使用(malloc),可是使用完了以后卻不歸還(free),結果你申請到的那塊內存你自己也不能再訪問(也許你把它的地址給弄丟了),而系統也不能再次將它分配給需要的程序。一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完后必須顯示釋放的內存。應用程序一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完后,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。 內存溢出:內存溢出 OOM (out of memory),是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個int,但給它存了long才能存下的數,那就是內存溢出。
*/
int main()
{char* strSrc="hello!";char* dest;dest=(char*)malloc(12);memset(dest,'\0',12);puts(strcpy(dest,strSrc));//若再srecpy會將之前的內容覆蓋掉char strdest[3]={'\0'};//可以將數組初始化strcpy(dest,"he");//會將之前的內容覆蓋掉,輸出heputs(dest);memset(strdest,'\0',sizeof(strdest)/sizeof(strdest[0]));//這個也可以將數組初始化strncpy(strdest,strSrc,6);//注意n的選擇當n > destin串長度,destin棧空間溢出產生崩潰異常。strdest[2]='\0';//將第三個元素賦值為\0,初始化的時候要用{}printf("strdest長度為:%d\n",strlen(strdest));puts(strdest);char* dest1;dest1=(char*)malloc(128);//malloc向內存申請了128個字節//dest1是訪問這片內存的唯一方式,若這個指針指向了別的地址//那么這片內存在程序釋放之前不會被釋放造成內存泄漏if(dest1==NULL){printf("開辟失敗!\n");}memset(dest1,'\0',128);free(dest1);//釋放開辟的指針//dest1="hello world";//如果這里寫如這段代碼,dest1本來指向malloc開辟的內存空間//然而這段代碼又將dest1指向了字符串,造成了malloc開辟的空間無指針指向,造成內存泄露//又雙引號引起來的字符串叫字符串常量,不可變,只能進行讀操作不能進行寫操作,否則將會出現段錯誤//段錯誤應該就是訪問了不可訪問的內存,這個內存區要么是不存在的,要么是受到系統保護的//這里就是因為寫入了這段代碼,造成了內存泄漏和段錯誤,找了半天錯誤char dest2[128]="hello world"; strcat(dest2, strSrc);puts(dest2);char *str1="123";//如果不同,在不同的字符處如果str1的字符大于str2的字符,則返回1,否則返回-1char *str2="12345";printf("若輸出負數表示str1比str2小,反之則大,相等則輸出0:%d\n",strcmp(str1,str2));system("pause");return 0;
}
strchr、strstr、strlwr、strupr、strtok
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
strchr函數:
函數原型:char *strchr(const char *str, int c)
參數:要被檢索的 C 字符串。在 str 中要搜索的字符。大小寫也有區分
功能:在參數str所指向的字符串中搜索第一次出現字符c(一個無符號字符)的位置。
返回值:返回一個指向該字符串中第一次出現的字符的指針,如果字符串中不包含該字符則返回NULL空指針。
*//*
strstr函數:
strstr(str1,str2) 函數用于判斷字符串str2是否是str1的子串。
如果是,則該函數返回 str1字符串從 str2第一次出現的位置開始到 str1結尾的字符串;否則,返回NULL。
函數原型:char* strstr( char*str,char* substr)------字符串也是指針
功能:strstr返回一個指針,指向substr在str中首次出現的位置。*//*
strlwr函數:
原型:extern char *strlwr(char *s);
功能:將字符串s參數轉換為小寫形式
說明:只轉換s參數中出現的大寫字母,不改變其它字符。返回指向s參數的指針。
兼容性說明:strlwr和strupr不是標準C庫函數,只能在VC中使用。linux gcc環境下需要自行定義這個函數。
*//*
strupr:將字符串s轉換為大寫形式。
函數原型:extern char *strupr(char *s);
說明:只轉換s中出現的小寫字母,不改變其它字符。返回指向s的指針。
兼容性說明:strupr不是標準C庫函數,只能在VC中使用。在linux gcc環境下需要自行定義這個函數。
*//*
strtok()函數:
函數原型:char *strtok(char *str, const char *delim)
str -- 要被分解成一組小字符串的字符串。
delim -- 包含分隔符的 C 字符串。
功能:作用于字符串s,以delim中的字符為分界符,將s切分成一個個子串;
如果,s為空值NULL,則函數保存的指針SAVE_PTR在下一次調用中將作為起始位置。
返回值:該函數返回被分解的第一個子字符串,如果沒有可檢索的字符串,則返回一個空指針。*/
void strtokPrint(char*p)
{int i=1;int j=0;char* psubs[3];//定義一個指針數組,將分割好的字符串存入const char str7[]=",";char* p1=NULL;p1=strtok(p,str7);while(p1!=NULL){printf("第%d次分割為:%s\n",i,p1);psubs[i-1]=p1;//將分割好的第一個字符串存入指針數組p1=strtok(NULL,str7);if(p1==NULL)break;i++;}for(j;j<i;j++){printf("輸出分割后的指針是:%s\n",psubs[j]);}
}
int main()
{char c='e';char* str="hello";char* ret=NULL;ret=strchr(str,c);//只可用來查找字符if(ret==NULL){printf("沒有找到\n");}printf("手動輸出的h的地址是;%p\n",str);printf("找到了strchr輸出的h的地址是;%p,字符是;%s\n",ret,ret);/*這里找到目標字符的地址后若用%s進行輸出,則將目標字符看做字符串的首地址會將目標字符后的字符串輸出,若指向輸出目標字符得取地址*ret*/char* str2="hello";char* str3="he";puts(strstr(str2,str3));//輸出的是hello,返回的是h的地址/*char* str4="HELLO"; puts(strlwr(str4));這種方式在linux環境下是可以的,在windows下會閃退所以換下一種字符串定義的方式(數組的形態)*/char str4[]="HELLO";puts(strlwr(str4));char str5[]="hello";//在windows下用法和strlwr一樣 puts(strupr(str5));//和strlwr一樣參數不能是字符,否則出現段錯誤char str6[]="feng,nan,nan,";//在windows下用法和strlwr一樣char* p=NULL; /*const char str7[]=",";//,占用2個字節要用雙引號p=strtok(str6,str7);//注意這里分隔符要用雙引號if(p!=NULL){printf("第一次輸出:%s\n",p);}puts(str6);//特別要注意分割處理后原字符串str6會變,變成第一個子字符串feng//獲取第二個字符串的時候要將目標字符串改成NULLp=strtok(NULL,",");if(p!=NULL){printf("第二次輸出:%s\n",p);}puts(str6);//特別要注意分割處理后原字符串str6會變,變成第一個子字符串,仍然是fengp=strtok(NULL,",");//獲取第三個字符串也是同樣的道理if(p!=NULL){printf("第三次輸出:%s\n",p);}puts(str6);以上代碼可優化為函數*/strtokPrint(str6);puts(str6);//因為傳入的是數組名相當于指針,所以原數組分割處理后原字符串str6會變,變成第一個子字符串,仍然是fengsystem("pause");return 0;
}
自己實現puts、gets、memset、strlen
#include <stdio.h>
#include <stdlib.h>
//實現puts函數
void myPuts(char* p)
{ //字符串明顯的特點是:結尾有'\0'while(*p!='\0'){putchar(*p++);//printf("%c",*p++);}putchar('\n');
}
//自己實現字符串的輸入函數
void myGets(char* p)
{if(p==NULL){printf("內存非法");return;//執行到return后函數不繼續向下執行}while(*p=getchar()){//賦值不是空字符就是真,是空字符就都是假if(*p=='\n'){return;}else{p++;}}
}
//修改myGets計算用戶輸入字符個數
int cntGets(char* p)
{int cnt=0;if(p==NULL){printf("內存非法");return;//執行到return后函數不繼續向下執行}while(*p=getchar()){if(*p=='\n'){return cnt;}else{cnt++;p++;}}
}
//自己實現strlen函數
void myStrlen(char*p)
{int cnt=0;/*while(*p!='\0'){ cnt++;p++;}*/while(*p++!='\0'){//先執行*p然后再++再*p cnt++;}printf("字符串長度是:%d",cnt);putchar('\n');
}
//自己實現memset函數
void myMemset(char*p,char a,int n)
{while(n){*p++=a;n--; }
}
int main()
{char str[128]={'\0'};char* p="hello!";myPuts(p);myPuts("請輸入你的字符串:");int ret=cntGets(str);printf("你輸入了%d個字符\n",ret);myStrlen(p);char* str1=NULL;str1=(char*)malloc(128);myMemset(str1,'a',128);str1[128]='\0';myPuts(str1);system("pause");return 0;
}
自己實現srtcpy、strncpy、strcat、strcmp、strchr、strstr、strlwr、strupr、strtok
#include <stdio.h>
#include <stdlib.h>
//實現strcpy,拷貝函數是將前面的全覆蓋掉
char* myStrcpy(char*data1,const char*data2)//源字符串參數用const修飾,防止修改源字符串。
{if(data1==NULL||data2==NULL){return NULL;}char* p=data1;//將data1的首地址給p,等返回時就會返回data1的首地址while((*data1++=*data2++)!='\0'){//*data1++=*data2++;}return p;//拷貝完成后指針在data1的末尾//返回目的地址,是為了實現鏈式操作
}//自己實現strncpy(),拷貝的是第二個字符串的前n個字符,前一個字符串的后面部分不變
char * myStrncpy(char*data1,char*data2,int n)
{if(data1==NULL||data2==NULL){return NULL;}char*p=data1;int i=0;for(i;i<n;i++){*data1=data2[i];data1++;}/*while(*data2!='\0' && n>0){*data1++=*data2++;n--;} */return p;
}//自己實現字符串的拼接函數strcat()
char* myStrcat(char*data1,char*data2)
{if(data1==NULL||data2==NULL){return NULL;}char*p=data1;while(*data1!='\0'){//若括號里寫*data1++!='\0'則在等于‘\0’后還會++一次data1++;} while(*data2!='\0'){*data1++=*data2++;}return p;
}//自己實現字符串比較函數strcmp()
int myStrcmp(const char* data1,const char* data2)
{if(data1==NULL||data2==NULL){return NULL;}while ((*data1) && (*data1 == *data2))//判斷有沒有到結尾和是否相等 { data1++; data2++; } if (*data1 > *data2) { return 1; } else if (*data1 < *data2) { return -1; } else { return 0; }
}
//自己實現字符查找函數strchr
char *myStrchr(const char *s,char c) //返回的是你要找的字符的地址
{for(;*s!=c;s++){if(*s == '\0') //說明找完了return NULL;//找完了還沒有。那就直接返回空咯}return s;//我們須要的字符的地址
}
/*
char * Strchr(char to[], char Ch)
{int i = 0;while (to[i] != Ch && to[i] != '\0')i++;return to[i] != '\0'?to + i : NULL;
}
*///自己實現strstr函數
const char* myStrstr(const char* src, const char* sub)
{const char *bp;const char *sp;if(!src || !sub){return src;}/* 遍歷src字符串 */while(*src){/* 用來遍歷子串 */bp = src;sp = sub;do{if(!*sp) /*到了sub的結束位置,返回src位置 */return src;}while(*bp++ == *sp ++);src ++;}return NULL;
}//自己實現strlwr函數
char* myStrlwr(char*data)
{char*p=data;while (*data!= '\0'){if (*data > 'A' && *data <= 'Z'){//*src += 0x20; *data += 32;}data++;}return p;
}
//自己實現strupr函數
char* myStrupr(char* data)
{char*p=data;while (*data != '\0'){if (*data >= 'a' && *data <= 'z'){//在ASCII表里大寫字符的值比對應小寫字符的值小32.//*p -= 0x20; // 0x20的十進制就是32*data -=32;}data++;}return p;}
//自己實現strtok函數
char *myStrtok(char *str,char *demion)
{static char *p_last = NULL;if(str == NULL && (str = p_last) == NULL){return NULL;} char *s = str;char *t= NULL;while(*s != '\0'){t= demion;while(*t != '\0'){if(*s == *t){p_last = s +1;if( s - str == NULL){str = p_last;break;}*s = '\0';return str;}t++;}s++;}return NULL;
}
int main()
{char dest[128]="HELLO hello!";//char* dest=NULL;char* src="HELLO hello!";//字符串常量不可被修改,只讀char* a=" ";//puts(strcpy(dest,src));//printf("長度為:%d\n",strlen(myStrcpy(dest,src)));//返回目的地址,是為了實現鏈式操作//puts(myStrcpy(dest,src));//若沒有返回值,不能將這段代碼直接寫入puts中,因為返回的是在data1末尾的指針,無輸出//puts(myStrncpy(dest,src,3));//puts(myStrcat(dest,src));//int ret=myStrcmp(dest,src);//printf("輸出:%d\n",ret);//puts(myStrstr(dest,src));//puts(myStrlwr(dest));puts(myStrupr(dest));puts(myStrtok(dest,a));//輸出HELLO//puts(myStrchr(src,'e'));system("pause");return 0;
}
指針補充:
字長:在同一時間中處理二進制數的位數叫字長。通常稱處理字長為8位數據的CPU叫8位CPU,32位CPU就是在同一時間內處理字長為32位的二進制數據。二進制的每一個0或1是組成二進制的最小單位,稱為一個比特(bit)
指針的大小與什么有關?1、cpu位數(32位數4字節,64位數8字節)
2、操作系統位數(32位數4字節,64位數8字節)
3、編譯器的位數(32位數4字節,64位數8字節)
4、字長由微處理器(CPU)對外數據通路的數據總線條數決定。
5、最小可尋址單位:內存的最小可尋址單位通常都是字節。也就是說一個指針地址值可對應內存中一個字節的空間。
6、尋址空間:尋址空間一般指的是CPU對于內存尋址的能力。CPU最大能查找多大范圍的地址叫做尋址能力 ,CPU的尋址能力以字節為單位 (字節是最小可尋址單位)。 如32位尋址的CPU可以尋址2的32次方大小的地址也就是4G,這也是為什么32位尋址的CPU最大能搭配4G內存的原因 ,再多的話CPU就找不到了。
7、這里CPU的尋址位數是由地址總線的位數決定,32位CPU的尋址位數不一定是32位,因為32位CPU中32的意義為字長。
8、有關尋址范圍計算解釋,對于32位尋址的CPU,其地址值為32位的二進制數,所以可以表示的最大地址為2的32次方(即4G,最大內存空間為4GB,這里G表示數量、GB表示容量)。同時我們不難看出,一個指針的值就是一個32位的二進制數,32位對應4字節(Byte)。 所以,指針的大小實際上是由CPU的尋址位數決定,而不是字長。
指針大小有關因素詳解:影響指針大小的因素