<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本篇的內容主要圍繞指標與陣列、指標與字串等之間的關係,以及進一步理解sizeof 、strlen 的使用與意義。
陣列是指具有相同型別元素的集合,字串常數是一個指向在連續空間裡存放的字元的首字元的地址的指標。我們會在下面理解陣列與字串陣列的不同。
sizeof 是一個操作符,是計算型別空間大小的。strlen 是針對字串的庫函數,用來求字串的長度。
對於陣列來說,陣列名都是首元素地址,除了這兩種情況外:
我們的目的是求下面各個 printf 語句輸出什麼。
#include <stdio.h> int main() { int a[] = { 1,2,3,4 }; printf("%dn", sizeof(a)); printf("%dn", sizeof(a + 0)); printf("%dn", sizeof(*a)); printf("%dn", sizeof(a + 1)); printf("%dn", sizeof(a[1])); printf("%dn", sizeof(&a)); printf("%dn", sizeof(*&a)); printf("%dn", sizeof(&a + 1)); printf("%dn", sizeof(&a[0])); printf("%dn", sizeof(&a[0] + 1)); return 0; }
#include <stdio.h> int main() { int a[] = { 1,2,3,4 }; printf("%dn", sizeof(a)); //sizeof 內部單獨放置陣列名,計算整個陣列的大小,結果為 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(a + 0)); //sizeof 內部沒有單獨放置陣列名,此時陣列名錶首元素地址,a+0 依然表示首元素地址 //故 sizeof 計算一個地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*a)); //sizeof 內部沒有單獨放置陣列名,此時陣列名錶首元素地址,*a 表對該地址解除參照 //即可得到 a 陣列的第一個元素,大小為 4(int型別) printf("%dn", sizeof(a + 1)); //sizeof 內部沒有單獨放置陣列名,此時陣列名錶首元素地址,a+1 表第二個元素地址 //故 sizeof 計算一個地址(指標)的大小為 4 or 8 printf("%dn", sizeof(a[1])); //sizeof 內部沒有單獨放置陣列名,a[1] 表陣列的第二個元素,此寫法可轉置為 *(a+1) //即計算的結果是第二個元素的型別大小,即 4(int型別) printf("%dn", sizeof(&a)); //sizeof 內部沒有單獨放置陣列名,而是放置了 &a ,表取出整個陣列的地址 //故 sizeof 計算一個地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*&a)); //sizeof 內部雖然看似沒有單獨放置陣列名,但是通過 &a 取出整個陣列地址 //然後通過 * 找到整個地址,與 sizeof(a) 沒有差別 //故這裡的 sizeof 計算的也是整個陣列的大小,即 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(&a + 1)); //sizeof 內部沒有單獨放置陣列名,&a+1 表取出整個陣列的地址,並向後跳躍一個陣列型別的大小 //即此時的地址是指向元素 4 的後面一塊 int 型別的記憶體空間 //故 sizeof 計算地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&a[0])); //sizeof 內部沒有單獨放置陣列名,&a[0] 表取出陣列第一個元素的地址 //故 sizeof 計算地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&a[0] + 1)); //sizeof 內部沒有單獨放置陣列名,&a[0]+1 表取出陣列第一個元素地址並向後跳躍一個 int 型別的大小 //故 sizeof 計算的是地址(指標)的大小為 4 or 8 return 0; }
#include <stdio.h> int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%dn", sizeof(arr)); printf("%dn", sizeof(arr + 0)); printf("%dn", sizeof(*arr)); printf("%dn", sizeof(arr[1])); printf("%dn", sizeof(&arr)); printf("%dn", sizeof(&arr + 1)); printf("%dn", sizeof(&arr[0] + 1)); printf("%dn", strlen(arr)); printf("%dn", strlen(arr + 0)); printf("%dn", strlen(*arr)); printf("%dn", strlen(arr[1])); printf("%dn", strlen(&arr)); printf("%dn", strlen(&arr + 1)); printf("%dn", strlen(&arr[0] + 1)); return 0; }
#include <stdio.h> int main() { char arr[] = { 'a','b','c','d','e','f' };//非字串!!!!!! printf("%dn", sizeof(arr)); //sizeof 內部單獨放置陣列名,故計算的是整個陣列的大小 //即大小為 1(char型別)*6(元素個數)=6 printf("%dn", sizeof(arr + 0)); //sizeof 內部沒有單獨放置陣列名,arr 表陣列首元素地址,arr+0 亦表示首元素地址 //故 sizeof 計算地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*arr)); //sizeof 內部沒有單獨放置陣列名,arr 表陣列首元素地址,*arr 表對該地址解除參照 //便得到陣列第一個元素 'a' ,故大小為 1(char型別) printf("%dn", sizeof(arr[1])); //sizeof 內部沒有單獨放置陣列名,arr[1] 表陣列第二個元素,即 'b' //故大小為 1(char型別) printf("%dn", sizeof(&arr)); //sizeof 內部沒有單獨放置陣列名,&arr 表取出整個陣列的地址 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&arr + 1)); //sizeof 內部沒有單獨放置陣列名,&arr+1 表取出整個陣列的地址並向後跳躍一個陣列型別的大小 //即指向元素 'f' 後一個 char 型別的空間 //故 sizeof 計算的是地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&arr[0] + 1)); //sizeof 內部沒有單獨放置陣列名,&arr[0]+1 表取出陣列一個元素的地址並向後跳躍一個 char 型別的大小 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", strlen(arr)); //strlen 不是 sizeof ,故 arr 表陣列首元素地址,strlen 會以此地址開始向後尋找 ' ' //但此陣列並不包含 ' ' ,故 strlen 的返回值為隨機值 printf("%dn", strlen(arr + 0)); //strlen 不是 sizeof ,arr+0 表首元素地址,strlen 的返回值也是一個隨機值 printf("%dn", strlen(*arr)); //strlen 不是 sizeof ,*arr 表對陣列首元素地址解除參照,得到字元 'a' ,其 ASCLL 碼值為 97 //strlen 會以 97 為起始地址向後尋找 ' ' //但個人理解認為:97 是一個沒有初始化的指標(地址),即野指標 //故這裡會報錯 printf("%dn", strlen(arr[1])); //arr[1] 表陣列的第二個元素 'b' ,其 ASCLL 碼值為 98 //strlen 會以 98 為起始地址向後尋找 ' ' //但個人理解認位:98 是一個沒有初始化的指標(地址),即野指標 //故這裡依然會報錯 printf("%dn", strlen(&arr)); //&arr 表取出整個陣列的地址,strlen 會以此作為起始地址向後尋找 ' ' //這裡需要注意,在 strlen 的函數宣告當中,引數是一個 char* 型別的指標 //也就是我們雖然傳參時傳了一個陣列指標,但是 strlen 接收時會自動強轉為 char* 型別指標 //故陣列並不包含 ' ' ,strlen 的返回值是一個隨機值 printf("%dn", strlen(&arr + 1)); //&arr+1 表取出整個陣列的地址並向後跳躍一個陣列型別的大小 //即指向了元素 'f' 的後一塊 char 型別的空間 //strlen 會以此地址作為起始地址向後尋找 ' ' //但因我們無法確定 ' ' 的位置,所以 strlen 的返回值是一個隨機值 printf("%dn", strlen(&arr[0] + 1)); //&arr[0]+1 表取出陣列首元素地址並向後跳躍一個 char 型別的大小 //即指向了元素 'b' ,strlen 會以此地址作為起始地址向後尋找 ' ' //但陣列中並不包含 ' ' ,故 strlen 的返回值是一個隨機值 return 0; }
我們把報錯的兩條語句註釋掉:
#include <stdio.h> int main() { char arr[] = "abcdef"; printf("%dn", sizeof(arr)); printf("%dn", sizeof(arr + 0)); printf("%dn", sizeof(*arr)); printf("%dn", sizeof(arr[1])); printf("%dn", sizeof(&arr)); printf("%dn", sizeof(&arr + 1)); printf("%dn", sizeof(&arr[0] + 1)); printf("%dn", strlen(arr)); printf("%dn", strlen(arr + 0)); printf("%dn", strlen(*arr)); printf("%dn", strlen(arr[1])); printf("%dn", strlen(&arr)); printf("%dn", strlen(&arr + 1)); printf("%dn", strlen(&arr[0] + 1)); return 0; }
#include <stdio.h> int main() { char arr[] = "abcdef";//注意陣列裡面放的是字串!!! printf("%dn", sizeof(arr)); //sizeof 內部單獨放置陣列名,即計算整個陣列的大小 //大小為 1(char型別)*7(元素個數)=7 printf("%dn", sizeof(arr + 0)); //sizeof 內部沒有單獨放置陣列名,arr+0 表陣列首元素地址 //故 sizeof 計算地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*arr)); //sizeof 內部沒有單獨放置陣列名,*arr 表對陣列首元素地址解除參照 //即得到字元 'b' ,故大小為 1(char型別) printf("%dn", sizeof(arr[1])); //sizeof 內部沒有單獨放置陣列名,arr[1] 表陣列第二個元素即字元 'b' //故大小為 1(char型別) printf("%dn", sizeof(&arr)); //sizeof 內部沒有單獨放置陣列名,&arr 表對整個陣列取地址 //故 sizeof 計算的地址(指標)大小為 4 or 8 printf("%dn", sizeof(&arr + 1)); //sizeof 內部沒有單獨放置陣列名,&arr+1 表取出整個陣列地址並向後跳躍一個陣列型別大小 //即指向元素 ' ' 後面一塊陣列型別大小的空間 //故 sizeof 計算的地址(指標)大小為 4 or 8 printf("%dn", sizeof(&arr[0] + 1)); //sizeof 內部沒有單獨放置陣列名,&arr[0]+1 表取出陣列首元素地址並向後跳躍一個 char 型別大小 //即指向陣列第二個元素 //故 sizeof 計算的地址(指標)大小為 4 or 8 printf("%dn", strlen(arr)); //strlen 不是 sizeof ,arr 表陣列首元素地址,strlen 會以此為起始地址向後尋找 ' ' //因為此陣列包含 ' ' ,故 strlen 的返回值為 6 printf("%dn", strlen(arr + 0)); //arr+0 表陣列首元素地址,strlen 會以此地址為起始地址向後尋找 ' ' //因為此陣列包含 ' ' ,故 strlen 的返回值為 6 printf("%dn", strlen(*arr)); //*arr 表對陣列首元素地址解除參照,得到字元 'a' ,其 ASCLL 碼值為 97 //故 strlen 會以此地址為起始地址向後尋找 ' ' //但個人理解認位: 97 是一個沒有初始化的指標(地址),即野指標 //故這裡會報錯 printf("%dn", strlen(arr[1])); //arr[1] 表陣列第二個元素,即字元 'b' ,其 ASCLL 碼值為 98 //strlen 會以此地址會起始地址向後尋找 ' ' //但個人理解認位:98 是一個沒有初始化的指標(地址),即野指標 //故這裡會報錯 printf("%dn", strlen(&arr)); //&arr 表取出整個陣列的地址,但觀察 strlen 函數的宣告可以發現 //strlen 的函數引數是一個 char* 型別的指標 //即我們傳參傳進去的是一個陣列指標,當 strlen 接收的時候,會將其強轉為字元指標 //故 strlen 會以陣列首元素地址為起始地址,向後尋找 ' ' //因為陣列包含 ' ' ,故 strlen 的返回值為 6 printf("%dn", strlen(&arr + 1)); //&arr+1 表取出整個陣列的地址並向後跳躍一個陣列型別大小 //即指向 ' ' 後一塊陣列型別的空間 //strlen 會以此地址為起始地址向後尋找 ' ' //但我們無法確定 ' ' 的具體位置,所以 strlen 會返回一個隨機值 printf("%dn", strlen(&arr[0] + 1)); //&arr[0]+1 表取出陣列首元素地址並向後跳躍一個 char 型別的大小 //即指向了陣列第二個元素的地址 //strlen 會以此地址作為起始地址向後尋找 ' ' //故 strlen 的返回值為 5 return 0; }
我們把報錯的語句註釋掉:
#include <stdio.h> int main() { char* p = "abcdef";//p 變數存放的是字串常數的首元素地址 printf("%dn", sizeof(p)); //sizeof 計算地址(指標)的大小為 4 or 8 printf("%dn", sizeof(p + 1)); //p+1 表字串常數的第二個元素的地址 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*p)); //*p 表對字串常數首元素地址解除參照。得到字元 'a' //故計算的大小為 1(char型別) printf("%dn", sizeof(p[0])); //p[0] 可改寫成 *(p+0) ,表對字串常數首元素地址解除參照,得到字元 'a' //即計算的大小為 1(char型別) printf("%dn", sizeof(&p)); //&p 表對 char* 型別指標取地址 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&p + 1)); //&p+1 表對 char* 型別指標變數 p 取地址並向後跳躍一個 char 型別的大小 //指向的空間是未知的 //但 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(&p[0] + 1)); //&p[0]+1 可改寫成 &(*(p+0))+1 ,表取出字串常數的首元素地址並向後跳躍一個 char 型別的大小 //即指向了字元 'b' //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", strlen(p)); //strlen 不是 sizeof ,p表字串首元素地址 //strlen 以此地址為起始地址,向後尋找 ' ' //故 strlen 的返回值為 6 printf("%dn", strlen(p + 1)); //p+1 表字串常數的第二個元素的地址,strlen 會以此為地址向後尋找 ' ' //故 strlen 的返回值為 5 printf("%dn", strlen(*p)); //*p 表字串常數首元素,即字元 'a',strlen 會以此為地址向後尋找 ' ' //但個人理解人為:'a' 的 ASCLL 碼值為 97 ,但 97 是一個沒有被初始化的指標(地址),即野指標 //故這裡會報錯 printf("%dn", strlen(p[0])); //p[0] 可改寫成 *(p+0) ,表字串常數首元素,即字元 'a',其 ASCLL 碼值為 97 //strlen 會以此地址為起始地址向後尋找 ' ' //但個人理解認位:97 是一個沒有被初始化的指標(地址),即野指標 //故這裡會報錯 printf("%dn", strlen(&p)); //&p 表取出 char* 型別指標變數的地址,strlen 以此地址為起始地址向後尋找 ' ' //但我們無法確定 ' ' 的位置 //故 strlen 會返回一個隨機值 printf("%dn", strlen(&p + 1)); //&p+1 表取出 char* 型別指標變數的地址並向後跳躍一個 char 型別的大小,strlen 以此地址為起始地址向後尋找 ' ' //但我們無法確定 ' '的位置,故 strlen 的返回值會返回一個隨機值 printf("%dn", strlen(&p[0] + 1)); //*p{0}+1 可改寫為 &(*(p+0))+1 ,表取出字串常數首元素地址並向後跳躍一個 char 型別的大小 //即指向了字串常數的第二個元素的地址,strlen 會以此地址為起始地址向後尋找 ' ' //故 strlen 的返回值為 5 return 0; }
我們對報錯的兩條語句註釋:
#include <stdio.h> int main() { int a[3][4] = { 0 }; printf("%dn", sizeof(a)); //sizeof 內部放置的是陣列名,故計算整個陣列的大小 //即大小為 4(int型別)*12(元素個數)=48 printf("%dn", sizeof(a[0][0])); //sizeof 內部沒有單獨放置陣列名,a[0][p] 表陣列首元素 //故 sizeof 的計算值為 4(int型別) printf("%dn", sizeof(a[0])); //sizeof 內部放置的看似不是單獨的陣列名,但 a[0] 表陣列的第一個元素 //此元素也是一個陣列 //故 sizeof 計算的大小為 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(a[0] + 1)); //sizeof 內部放置的不是單獨的陣列名,a[0] 表二維陣列的第一個元素,即拿到了一個陣列 //a[0]+1 表二維陣列的第一個陣列元素的地址並向後跳躍一個 int 型別的大小 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*(a[0] + 1))); //*(a[0]+1) 表對二維陣列的第一個陣列元素的地址並向後跳躍一個 int 型別的大小的解除參照 //即找到了二維陣列中的某一個元素 //故 sizeof 計算的大小為 4(int型別) printf("%dn", sizeof(a + 1)); //sizeof 內部沒有單獨放置陣列名,a+1 表二維陣列的首元素地址並向後跳躍一個一維陣列型別的大小 //即指向了二維陣列的第二個陣列元素的地址 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*(a + 1))); //*(a+1) 表對二維陣列的首元素地址並向後跳躍一個一維陣列型別的大小的解除參照 //即得到了二維陣列的第二個元素 //此元素為一個一維陣列,故 sizeof 計算的大小為 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(&a[0] + 1)); //&a[0]+1 表二維陣列的首元素取地址並向後跳躍一個一維陣列的型別大小 //指向了二維陣列的第二個元素 //故 sizeof 計算的地址(指標)的大小為 4 or 8 printf("%dn", sizeof(*(&a[0] + 1))); //*(&a[0]+1) 表對二維陣列的首元素取地址並向後跳躍一個一維陣列的型別大小的解除參照 //即得到了二維陣列的第二個元素 //此元素是一個一維陣列,故 sizeof 計算的大小的 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(*a)); //sizeof 內部沒有單獨放置陣列名,*a 表對二維陣列首元素地址解除參照 //得到一個一維陣列 //故 sizeof 計算的大小為 4(int型別)*4(元素個數)=16 printf("%dn", sizeof(a[3])); //a[3] 表二維陣列的第三個元素 //需要說明的是,sizeof 只對型別感興趣 //也就是說,二維陣列雖然不存在第三個元素,但它的型別依舊是二維陣列 //故 sizeof 計算的是 4(int型別)*4(元素個數)=16 return 0; }
到此這篇關於C語言例題講解指標與陣列的文章就介紹到這了,更多相關C語言指標與陣列內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45