摘要:萬字詳解與的用法數(shù)組名的意義一維數(shù)組用法字符數(shù)組用法的用法字符串數(shù)組用法的用法指針與字符串用法用法二維數(shù)組數(shù)組名的意義在講所有東西之前,需要先明確一個關(guān)鍵問題數(shù)組名,這里的數(shù)組名表示整個數(shù)組,計算的是整個數(shù)組的大小,單
在講所有東西之前,需要先明確一個關(guān)鍵問題:
//一維數(shù)組 int a[] = { 1,2,3,4 }; printf("%d/n", sizeof(a)); printf("%d/n", sizeof(a + 0)); printf("%d/n", sizeof(*a)); printf("%d/n", sizeof(a + 1)); printf("%d/n", sizeof(a[1])); printf("%d/n", sizeof(&a)); printf("%d/n", sizeof(*&a)); printf("%d/n", sizeof(&a + 1)); printf("%d/n", sizeof(&a[0])); printf("%d/n", sizeof(&a[0] + 1));
運行結(jié)果:
解:
printf("%d/n", sizeof(a)); 16字節(jié)
因為int a[ ]里有4個元素,每個元素是int類型,占四個字節(jié),所以整個數(shù)組大小為16字節(jié)
printf("%d/n", sizeof(a + 0)); 4/8字節(jié)在32/64位平臺下
此時此刻的數(shù)組名a表示的是首元素地址,首元素地址+0,還是首元素地址,地址的大小為 4/8在32/64位平臺下
printf("%d/n", sizeof(*a)); 4字節(jié)
a是數(shù)組名,表示首元素地址,然后對首元素地址解引用,所以*a就是首元素,首元素是個int型,大小為4字節(jié)
printf("%d/n", sizeof(a + 1)); 4/8字節(jié)在32/64位平臺下
a是數(shù)組名,表示首元素地址,a+1是第二個元素的地址,所以大小為4/8字節(jié)在32/64位平臺下
printf("%d/n", sizeof(a[1])); 4字節(jié)
a[1]就是第二個元素,大小為4字節(jié)
printf("%d/n", sizeof(&a)); 大小為4/8字節(jié)在32/64位平臺下
&a取出的是整個數(shù)組的地址(從數(shù)值的角度看等于首元素地址),只要是地址,大小就為4/8字節(jié)在32/64位平臺下
printf("%d/n", sizeof(*&a)); 16字節(jié)
&a取出的是整個數(shù)組的地址,* &a是對整個數(shù)組的地址解引用,拿到的是整個數(shù)組,所以大小為16字節(jié)
printf("%d/n", sizeof(&a + 1)); 4/8字節(jié)在32/64位平臺下
&a是數(shù)組的地址,&a+1是數(shù)組的地址+1,雖然相當于跳過了整個數(shù)組,但還是一個地址,所以大小還是4/8
printf("%d/n", sizeof(&a[0])); 4/8字節(jié)在32/64位平臺下
第1個元素地址,地址大小為4/8字節(jié)在32/64位平臺下
printf("%d/n", sizeof(&a[0] + 1)); 4/8字節(jié)在32/64位平臺下
第一個元素地址+1,就是第二個元素地址,地址大小為4/8字節(jié)在32/64位平臺下
char arr[] = {"a","b","c","d","e","f"}; printf("%d/n", sizeof(arr)); printf("%d/n", sizeof(arr+0)); printf("%d/n", sizeof(*arr)); printf("%d/n", sizeof(arr[1])); printf("%d/n", sizeof(&arr)); printf("%d/n", sizeof(&arr+1)); printf("%d/n", sizeof(&arr[0]+1));
運行結(jié)果:
解:
printf("%d/n", sizeof(arr)); 6
此時此刻,sizeof(數(shù)組名) 計算的是整個數(shù)組的大小,這個數(shù)組有6個char類型元素,所以大小為6字節(jié)
printf("%d/n", sizeof(arr+0)); 4/8
這里的arr表示首元素地址,+0之后還是首元素a的地址,只要是地址,所以大小為4/8字節(jié)
printf("%d/n", sizeof(*arr)); 1
arr是首元素地址,對首元素地址解引用,即得到首元素 a ,a是char類型,所以大小為1
printf("%d/n", sizeof(arr[1])); 1
arr[1]表示的就是第二個元素b,大小為1
printf("%d/n", sizeof(&arr)); 4/8
這里&arr取的是整個數(shù)組的地址,是地址,所以大小為4/8字節(jié)
printf("%d/n", sizeof(&arr+1)); 4/8
&arr是數(shù)組的地址,&arr+1是數(shù)組的地址+1,雖然相當于跳過了整個數(shù)組,但還是一個地址,所以大小還是4/8字節(jié)
printf("%d/n", sizeof(&arr[0]+1)); 4/8
&arr[0]是首元素地址,+1后取到的是第二位元素的地址,也就是 b 的地址,大小為4/8字節(jié);
strlen庫函數(shù)是什么?請看下圖
請看題:
char arr[] = {"a","b","c","d","e","f"}; printf("%d/n", strlen(arr)); printf("%d/n", strlen(arr+0)); printf("%d/n", strlen(*arr)); printf("%d/n", strlen(arr[1])); printf("%d/n", strlen(&arr)); printf("%d/n", strlen(&arr+1)); printf("%d/n", strlen(&arr[0]+1));
解:
printf("%d/n", strlen(arr)); 結(jié)果是未知數(shù)即隨機值
因為arr是首元素地址,strlen函數(shù)拿到一個地址,從這個地址一路往后讀取計數(shù),直到讀到 /0 為止,然鵝在arr這個字符數(shù)組里,沒有 /0 讓其讀取,所以它會順著內(nèi)存地址一直往后,具體哪個內(nèi)存單元里存有 /0 是未知的,所以長度結(jié)果就是個隨機未知數(shù)
printf("%d/n", strlen(arr+0)); 結(jié)果是隨機值
arr是首元素地址,+0后還是首元素地址,情況與上一題同理,結(jié)果是隨機數(shù)
printf("%d/n", strlen(*arr)); 系統(tǒng)報錯
*arr是對首元素地址解引用,得到的就是 字符a ,strlen接收到的其實是字符a的ASCII碼值97 ,這個97不是一個合法地址,是個野指針,所以這行代碼會報錯
printf("%d/n", strlen(arr[1])); 系統(tǒng)報錯
arr[1]是第二位元素,就是字符 b ,strlen接收到的是字符 b 的ASCII碼值98,與上同理,會報錯
printf("%d/n", strlen(&arr)); 隨機值
&arr取到的是整個數(shù)組的地址,它的值實際上等于首元素地址,由于strlen函數(shù)的類型是char* ,傳過來之后會進行一個類型的隱式轉(zhuǎn)換,地址類型可能會不一樣,但是strlen能接收這個地址,即接收到首元素地址并由此往后計數(shù),所以結(jié)果也是一個隨機值
printf("%d/n", strlen(&arr+1));結(jié)果是一個隨機值,與strlen(&arr)得到的隨機值相差6
&arr是取整個數(shù)組的地址,+1是跳過整個數(shù)組,拿到的是整個數(shù)組之后的地址,所以同理,結(jié)果也是一個隨機值,只不過這個隨機值與strlen(arr)得到的隨機值相差6,如圖:
printf("%d/n", strlen(&arr[0]+1)); 隨機值
&arr[0]是取第一個元素地址,+1是取到第二個元素地址,即從 字符b 開始向后計數(shù),但是不知道 /0 會出現(xiàn)在后邊內(nèi)存的哪個位置,所以結(jié)果也是隨機數(shù)
char arr[] = "abcdef"; printf("%d/n", sizeof(arr)); printf("%d/n", sizeof(arr+0)); printf("%d/n", sizeof(*arr)); printf("%d/n", sizeof(arr[1])); printf("%d/n", sizeof(&arr)); printf("%d/n", sizeof(&arr+1)); printf("%d/n", sizeof(&arr[0]+1));
解:
printf("%d/n", sizeof(arr)); 7字節(jié)
abcdef/0 一共7個字節(jié)
printf("%d/n", sizeof(arr+0)); 4/8
arr表示首元素字符地址,+0之后還是首元素字符 a 的地址,大小為4/8字節(jié)
printf("%d/n", sizeof(*arr)); 1字節(jié)
arr是首元素地址,解引用*arr后就是首元素 字符a,大小為1字節(jié)
printf("%d/n", sizeof(arr[1])); 1字節(jié)
arr[1] 表示第二個元素,也就是字符 b ,大小為1字節(jié)
printf("%d/n", sizeof(&arr)); 4/8字節(jié)
&arr 是整個數(shù)組的地址,數(shù)組的地址也是地址,大小為4/8字節(jié)
printf("%d/n", sizeof(&arr+1)); 4/8字節(jié)
&arr 是數(shù)組的地址,&arr+1是跳過整個數(shù)組,得到數(shù)組后一位的地址,4//8字節(jié)
printf("%d/n", sizeof(&arr[0]+1)); 4//8字節(jié)
&arr[0]是第一個元素地址,&arr[0]+1 是第二個元素地址,大小為4/8字節(jié)
char arr[] = "abcdef"; printf("%d/n", strlen(arr)); printf("%d/n", strlen(arr+0)); printf("%d/n", strlen(*arr)); printf("%d/n", strlen(arr[1])); printf("%d/n", strlen(&arr)); printf("%d/n", strlen(&arr+1)); printf("%d/n", strlen(&arr[0]+1));
解:
printf("%d/n", strlen(arr)); 6
strlen只對abcdef計數(shù), 不算/0一共6個字符,也就是6字節(jié)
printf("%d/n", strlen(arr+0)); 6
arr是首元素地址,+0后還是首元素的地址,從首地址開始計數(shù),仍然為6字節(jié)
printf("%d/n", strlen(*arr)); 系統(tǒng)報錯 printf("%d/n", strlen(arr[1])); 系統(tǒng)報錯
*arr傳入的是數(shù)組首元素,就是字符a,strlen接收到的其實是字符a的ASCII碼值97,97不是合法地址,相當于野指針,所以會報錯
arr[1]同理,傳入的是第二個元素字符 b ,strlen接收到的是字符b 的ASCII碼值98,是非法地址,所以也會報錯
printf("%d/n", strlen(&arr)); 6
&arr是取得整個數(shù)組的地址,數(shù)值上等于首元素地址,strlen接收到的就是首元素地址,于是從首元素開始計數(shù),結(jié)果為6字節(jié)
printf("%d/n", strlen(&arr+1)); 隨機值
&arr+1得到的地址如上圖所示,一直向后讀取,不知道什么時候才能讀取到/0,所以strlen得到的結(jié)果為隨機值
printf("%d/n", strlen(&arr[0]+1));5字節(jié)
&arr[0]是第一個元素地址,+1之后得到第二個元素地址,從第二個元素地址開始讀取,讀到/0前,一共5個字節(jié)
const char *p = "abcdef"; printf("%d/n", sizeof(p)); printf("%d/n", sizeof(p+1)); printf("%d/n", sizeof(*p)); printf("%d/n", sizeof(p[0])); printf("%d/n", sizeof(&p)); printf("%d/n", sizeof(&p+1)); printf("%d/n", sizeof(&p[0]+1));
解:
printf("%d/n", sizeof(p)); 4/8字節(jié)
p是一個指針變量,存的是字符串首元素地址,所以是4/8字節(jié)
printf("%d/n", sizeof(p+1)); 4/8字節(jié)
p是一個指針變量,存的是字符串首元素址,+1之后就是字符串第二個元素的地址,也就是 b 的地址,是4/8個字節(jié)
printf("%d/n", sizeof(*p)); 1字節(jié)
p是一個指針變量,存的是字符串首元素地址,對其解引用,*p得到的是字符 a ,類型為char,大小為1個字節(jié)
printf("%d/n", sizeof(p[0])); 1字節(jié)
p[0] = *(p+0) = *p,這三種寫法表示的都是首元素字符 a ,大小為1個字節(jié)
printf("%d/n", sizeof(&p)); 4/8字節(jié)
p是一個指針變量,是一個地址,對指針變量取地址,得到的是一個地址的地址,還是一個地址,所以大小還是4/8字節(jié)
printf("%d/n", sizeof(&p+1)); 4/8字節(jié)
p是個指針變量,字符串通過指針存到內(nèi)存中,其實也可以理解成這是內(nèi)存中一塊連續(xù)的儲存空間,就像數(shù)組一樣,這里的 &p+1 ,p是一個指向字符串首元素的一級指針,&p是指針變量p的地址,是一個二級指針,+1之后,相當于二級指針+1,指向的是一塊我們不知道的未知空間,但說到底還是一個地址,大小仍是4/8字節(jié),如圖所示:
printf("%d/n", sizeof(&p[0]+1)); 4/8字節(jié)
字符串也是一塊連續(xù)空間,可以像數(shù)組一樣通過 [ ] 訪問,p[0] = *(p+0) = *p這三種表示方法都可以表示字符串元素,這里&p[0]表示首元素地址,+1就是第二個元素字符b的地址,是地址,大小為4/8字節(jié)
const char *p = "abcdef"; printf("%d/n", strlen(p)); printf("%d/n", strlen(p+1)); printf("%d/n"
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/119669.html
摘要:前言由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
摘要:目錄前言架構(gòu)安裝第一個爬蟲爬取有道翻譯創(chuàng)建項目創(chuàng)建創(chuàng)建解析運行爬蟲爬取單詞釋義下載單詞語音文件前言學(xué)習(xí)有一段時間了,當時想要獲取一下百度漢字的解析,又不想一個個漢字去搜,復(fù)制粘貼太費勁,考慮到爬蟲的便利性,這篇文章是介紹一個爬蟲框架, 目錄 前言 架構(gòu) 安裝 第一個爬蟲:爬取有道翻譯 創(chuàng)建項目 創(chuàng)建Item 創(chuàng)建Spider 解析 運行爬蟲-爬取單詞釋義 下載單詞語音文件 ...
摘要:在項目中,為滿足以上要求,我們將大量的參數(shù)配置在或文件中,通過注解,我們可以方便的獲取這些參數(shù)值使用配置模塊假設(shè)我們正在搭建一個發(fā)送郵件的模塊。這使得在不影響其他模塊的情況下重構(gòu)一個模塊中的屬性變得容易。 在編寫項目代碼時,我們要求更靈活的配置,更好的模塊化整合。在 Spring Boot 項目中,為滿足以上要求,我們將大量的參數(shù)配置在 application.properties 或...
摘要:在項目中,為滿足以上要求,我們將大量的參數(shù)配置在或文件中,通過注解,我們可以方便的獲取這些參數(shù)值使用配置模塊假設(shè)我們正在搭建一個發(fā)送郵件的模塊。這使得在不影響其他模塊的情況下重構(gòu)一個模塊中的屬性變得容易。 在編寫項目代碼時,我們要求更靈活的配置,更好的模塊化整合。在 Spring Boot 項目中,為滿足以上要求,我們將大量的參數(shù)配置在 application.properties 或...
閱讀 3917·2021-09-09 09:33
閱讀 1773·2021-09-06 15:14
閱讀 1919·2019-08-30 15:44
閱讀 3074·2019-08-29 18:36
閱讀 3765·2019-08-29 16:22
閱讀 2095·2019-08-29 16:21
閱讀 2530·2019-08-29 15:42
閱讀 1648·2019-08-29 11:00