日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

C语言入坑指南-数组之谜

發(fā)布時(shí)間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言入坑指南-数组之谜 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在C語(yǔ)言中,數(shù)組和指針?biāo)坪蹩偸恰皶崦敛磺濉?#xff0c;有時(shí)候很容易把它們混淆。本文就來(lái)理一理數(shù)組和指針之間到底有哪些異同。

數(shù)組回顧

在分析之前,我們不妨回顧一下數(shù)組的知識(shí)。數(shù)組是可以存儲(chǔ)一個(gè)固定大小的相同類型元素的順序集合。為了便于我們說(shuō)明,假設(shè)有以下數(shù)組聲明:

int?a[5]; char?b[]?=?"hello";
  • 數(shù)組大小必須在編譯期就作為一個(gè)常數(shù)確定下來(lái)。

  • 但C99中引入了變長(zhǎng)數(shù)組,允許數(shù)組的維度是表達(dá)式 ,但在數(shù)組分配內(nèi)存時(shí),其表達(dá)式的值可以被求出。

  • 數(shù)組下標(biāo)運(yùn)算實(shí)際上都是通過(guò)指針進(jìn)行的,也就是說(shuō)a[4]與*(a+4)是等價(jià)的,甚至你會(huì)發(fā)現(xiàn)和4[a]也是一樣的。

  • 數(shù)組名一般代表了指向該數(shù)組下標(biāo)為0的元素的指針,并且printf("%s\n",hello)與printf("%s\n",&hello[0])等效。

數(shù)組和指針不相等

考慮下面的聲明:

int?c[4];//假設(shè)int占4字節(jié) int?*d;

對(duì)于上面的聲明,編譯器會(huì)給c預(yù)留內(nèi)存空間4*4字節(jié),并且數(shù)組名代表著指向數(shù)組第一個(gè)元素的指針。但對(duì)于d,卻只為指針本身保留了內(nèi)存空間。

c[3];????????//合法 *(c+3);??????//合法 *d;??????????//不合法,d指向了內(nèi)存中不確定位置 c++;????????//不合法,一維數(shù)組名是指針常量,常量不能被修改掉 d++;????????//可通過(guò)編譯

另外,下面的兩種情況也是不一樣的:

char?c[]?=?"hello"; char?*d?=?"hello";

前者對(duì)字符數(shù)組a進(jìn)行了初始化,后者將d指向了字符串常量。字符串常量存儲(chǔ)在只讀區(qū),因此有下面的操作:

?c[0]?=?'H';??//合法,可修改數(shù)組內(nèi)容*d?=?'H';????//不合法,字符串常量?jī)?nèi)容不可更改d[0]?=?'H'???//不合法

數(shù)組名的含義

絕大多數(shù)情況,數(shù)組名都代表著指向該數(shù)組中下標(biāo)為0的元素的指針,但是有例外:

int?e[4];//假設(shè)int為4字節(jié) sizeof(e);

上面的sizeof(e)的值并非4或8(指針占用空間),而是4*4 = 16。也就是說(shuō),當(dāng)數(shù)組名被用作運(yùn)算符sizeof的參數(shù)時(shí),它的計(jì)算結(jié)果是整個(gè)數(shù)組的大小,而非第一個(gè)元素的指針大小。

int?temp[5]; char?*p?=?&temp; char?*q?=?temp;

在這里,p和q的值是一樣的,含義卻不一樣,前者是指向數(shù)組的指針,而后者是指向該數(shù)組中下標(biāo)為0的元素的指針。因此p+1指向了temp的末尾,而q+1指向了temp的第2個(gè)元素。

數(shù)組長(zhǎng)度計(jì)算

如何計(jì)算數(shù)組長(zhǎng)度?考慮下面的代碼:

int?f[]?=?{1,2,3,4,5,6}; int?*g?=?f; size_t?len_f?=?sizeof(f)/sizeof(int)//正確計(jì)算方法 size_t?len_g?=?sizeof(g)/sizeof(int)

上面的len_f和len_g的值相等嗎?顯然并不相等。事實(shí)上,只有l(wèi)en_f得到了數(shù)組f的長(zhǎng)度,而len_g的值并沒有任何實(shí)際意義。

不能作為參數(shù)的數(shù)組

所謂的數(shù)組不能作為參數(shù),并不是指聲明的數(shù)組不能作為參數(shù)傳遞,而是指當(dāng)數(shù)組名作為參數(shù)時(shí),數(shù)組名會(huì)被轉(zhuǎn)換為指向該數(shù)組下標(biāo)為0的元素的指針。

size_t?arrayLen(const?int?*arr); size_t?arrayLen(const?int?arr[]);

我們來(lái)看一個(gè)例子,說(shuō)明數(shù)組作為參數(shù)的情況:

#include?<stdio.h> int?arraySum(const?int?arr[]) {unsigned?int?loop?=?0;/*循環(huán)前計(jì)算好長(zhǎng)度,提高性能*/unsigned?int?len?=?sizeof(arr)/sizeof(int);int?sum?=?0;if(NULL?==?arr){return?0;}for(loop?=?0;?loop?<?len;?loop++){sum+=arr[loop];}return?sum;??? } int?main(void) {int?a[]?=?{1,2,3,4,5,6};int?sum?=?arraySum(a);printf("arr?sum?is?%d",sum);return?0; }

我們運(yùn)行上面的程序,發(fā)現(xiàn)最終結(jié)果并不是我們預(yù)期的21,而是3。問題在于,a作為參數(shù)傳入到arraySum中時(shí),它是作為指針的,那么在函數(shù)內(nèi)部計(jì)算sizeof(arr)自然只是得到了指針占用的內(nèi)存大小。對(duì)于64位程序,這個(gè)大小是8,那么len的值為2,最終只計(jì)算了兩個(gè)元素的和。

思考:該如何修改上面的程序才能得到正確的結(jié)果?

總結(jié)

我們來(lái)總結(jié)一下前面的核心內(nèi)容:

  • 數(shù)組下標(biāo)運(yùn)算實(shí)際上都是通過(guò)指針進(jìn)行的。

  • 數(shù)組名代表著指向該數(shù)組中下標(biāo)為0的元素的指針,但有例外:sizeof(數(shù)組名)返回整個(gè)數(shù)組的大小,而非指針大小;&數(shù)組名返回一個(gè)指向數(shù)組的指針,而不是指向該數(shù)組中下標(biāo)為0的元素的指針的指針。

  • 數(shù)組名作為參數(shù)時(shí),數(shù)組名會(huì)被轉(zhuǎn)換成指向該數(shù)組下標(biāo)為0的元素的指針。

  • 指針操作可能比下標(biāo)操作效率高,但可維護(hù)性卻不一定有下標(biāo)操作好。

  • 數(shù)組和指針不相等。

思考

下面的代碼輸出結(jié)果是什么?

#include<stdio.h> int?main(void) {int?a[5]?=?{1,2,3,4,5};int?*p?=?(int*)(&a+1);printf("%d,%d",*(a+1),*(p-1));return?0; }

掃碼或長(zhǎng)按關(guān)注

回復(fù)「?加群?」進(jìn)入技術(shù)群聊

總結(jié)

以上是生活随笔為你收集整理的C语言入坑指南-数组之谜的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。