指针c语言与数组,C语言指针与数组
C語言指針與數(shù)組
數(shù)組的下標應(yīng)該從0還是1開始? 我提議的妥協(xié)方案是0.5,可惜他們未予認真考慮便一口回絕 ? ?-- Stan Kelly-Bootle
1. 數(shù)組并非指針
為什么很多人會認為指針和數(shù)組始終應(yīng)該可以互換的呢? 因為對數(shù)組的引用總是可以寫成對指針的引用,而且確實存在一種指針和數(shù)組的定義完全相同的上下文環(huán)境,
不幸的是,這只是數(shù)組的一種極為普通的用法,并非所用情況下都是如此。
2. 什么是聲明,什么是定義
C語言中對象必須有且只有一個定義,但它可以有多個extern聲明.
定義:只能出現(xiàn)在一個地方,確定對象的類型并分配內(nèi)存,用于創(chuàng)建新的對象,例如 int a[100]
聲明:可以多次出現(xiàn),描述對象的類型,用于指代其他地方定義的對象(例如在其他文件里) 例如 extern int a[100]
extern對象聲明告訴編譯器對象的類型和名字,對象的內(nèi)存分配則在別處進行
3. 數(shù)組與指針的區(qū)別
出現(xiàn)在賦值左邊的符號被稱為 左值, 出現(xiàn)在賦值右邊的符號被稱為 右值。
編譯器為每個變量分配一個地址(左值),這個地址在編譯時可知,并且該變量在運行時一直保存于這個地址中。
存儲于變量中的值(右值)只有在運行時才可知,如果需要用到變量中存儲的值,編譯器就發(fā)出指令從指定地址讀入變量并將它存于寄存器中。
例如: char a[9] = "abcdefgh"; ? c = a[i]
假設(shè)編譯器符號表具有一個地址9980
運行時步驟1:取 i 的值,將它與 9980 相加 (基址加偏移量)
運行時步驟2:取地址 [9980+i] 的內(nèi)容
例如:char* p; ?c = *p;
假設(shè)編譯器符號表有一個符號p,它的地址為4624
運行時步驟1:取地址 4624 的內(nèi)容,假設(shè)是 1024
運行時步驟2:取地址1024的內(nèi)容
例如:char* p = "abcdefgh" ? c = p[i]
假設(shè)編譯器符號表有一個p,地址為 4624
運行時步驟1:取地址4624的內(nèi)容,假設(shè)是 1024
運行時步驟2:取得 i 的值,并將它與 1024 相加 ?(基址加偏移量)
運行時步驟3:取地址 [1024+i] 的內(nèi)容
指針
數(shù)組
保存數(shù)組的地址
保存數(shù)據(jù)
間接訪問數(shù)據(jù),首先取指針的內(nèi)容,把它作為地址,然后從這個地址提取數(shù)據(jù)。
如果指針有一個下標[i],就把指針的內(nèi)容?加上i作為地址,從中提取數(shù)據(jù)
直接訪問數(shù)據(jù) a[i]只是簡單的以a+i作為地址取數(shù)據(jù)
通常用于動態(tài)數(shù)據(jù)結(jié)構(gòu)
通常用于存儲數(shù)目固定且數(shù)據(jù)類型相同的元素
相關(guān)的函數(shù)為 malloc free
隱式分配和刪除
通常指向匿名數(shù)據(jù)
自身即為數(shù)據(jù)名
定義指針時,編譯器沒有為指針所指向的對象分配空間,只是分配指針本身的空間
ANSI C中,初始化指針時所創(chuàng)建的字符串常量所定義為 只讀。在有些編譯器中,字符串常量被存放在只允許讀取的文本段中,以防止它被修改
char* ptr = "hello world" ? ?// 這種寫法是非常不推薦的,因為 ptr 所指對象是只讀的,這將隱式的將 const 轉(zhuǎn) non-const,任何對 ptr 的修改都會 coredump
const char* ptr = "hello world" ? // 這種寫法明確表示 ptr 的const屬性,這時對 ptr 所指對象的修改都會 在編譯時報錯
char a[] = "hello world" ? ? ? ? ? ? ?//這種寫法表明 數(shù)組中元素都是可修改的,但是數(shù)組名是不可修改的左值,即數(shù)組首地址不可以改變,是常量
4. 什么時候數(shù)組與指針相同
所有作為函數(shù)參數(shù)的數(shù)組名可以通過編譯器轉(zhuǎn)換為指針
數(shù)組的聲明就是數(shù)組,指針的聲明就是指針,兩者不能混淆
注意:如果定義一個數(shù)組,在其他文件中對它extern聲明時也必須把它聲明為數(shù)組,指針也是如此
在使用數(shù)組(在語句或表達式中引用)時,數(shù)組總是可以寫成指針的形式
數(shù)組下標表達式總是可以改寫成帶偏移量的指針表達式
什么時候數(shù)組和指針是相同的:
規(guī)則1:表達式中的數(shù)組名(與聲明不同)被編譯器當作一個指向該數(shù)組第一個元素的指針 (具體見 ANSI C標準 第6.2.2.1 節(jié))
規(guī)則2:下標總是與指針的偏移量相同(具體見ANSI C標準 第6.3.2.1 節(jié))
規(guī)則3:在函數(shù)參數(shù)的聲明中,數(shù)組名被編譯器當作指向該數(shù)組第一個元素的指針(具體見ANSI C標準 第6.7.1 節(jié))
其實規(guī)則1和規(guī)則1合起來理解如下:對數(shù)組下標的引用總是寫成"一個指向數(shù)組的起始地址的指針加上偏移量"
對數(shù)組的引用如a[i]在編譯時總是被編譯器改寫成*(a+i)指針訪問的形式
"作為函數(shù)參數(shù)的數(shù)組名"等同于指針
void func(int* arg);
void func(int arg[10]);
void func(int arg[]);
上述三種形式是完全等同的
5. 為什么C語言把數(shù)組形參當作指針
把作為形參的數(shù)組和指針等同起來是出于效率原因的考慮
在C語言中,所有非數(shù)組形式的數(shù)據(jù)實參均以傳值形式(對實參做一份拷貝并傳遞給調(diào)用的函數(shù),函數(shù)不能修改作為實參的實際變量的值,而只能修改傳遞給它的那份拷貝)調(diào)用
C語言允許程序員把形參聲明為數(shù)組(程序員打算傳遞給函數(shù)的東西)或者指針(函數(shù)實際所接收到的東西)
不管程序員實際所寫的是哪種形式,函數(shù)并不自動知道指針所指數(shù)組共有多少個元素,所以必須有個約定,如數(shù)組以NULL結(jié)尾或者另一個附加的參數(shù)表示數(shù)組的范圍
可以通過向函數(shù)傳遞一個指向數(shù)組第一個元素的指針來訪問整個數(shù)組,但也可以讓指針指向任何一個元素,這樣傳遞給函數(shù)的就是從該元素之后的數(shù)組片段
C語言指針和數(shù)組知識總結(jié)(上)
C語言指針和數(shù)組知識總結(jié)(上) 一.指針的基礎(chǔ) 1.C語言中,變量的值能夠通過指針來改變,打印指針的語句符號可以是: ?%08x 2.指針的本質(zhì) 指針的本質(zhì)就是變量,那么既然是變量,那么一定會分配地址 ...
C語言指針與數(shù)組的定義與聲明易錯分析
部分摘自 1.定義為數(shù)組,聲明為指針 在文件1中定義: char a[100]; 在文件2中聲明: extern char *a; //這樣是錯誤的 這里的extern告 ...
11-C語言指針&;一維數(shù)組&;字符串
一.用指針遍歷數(shù)組元素 1.最普通的遍歷方式是用數(shù)組下標來遍歷元素 1 // 定義一個int類型的數(shù)組 2 int a[4] = {1, 2, 3, 4}; 3 4 int i; 5 for (i = ...
c語言指針,數(shù)組
指針:說簡單點就是一個地址.例如int *p,p是個變量,里面放的是地址0x0000,同理,每一個指針,不管什么類型,都是地址,也就是空間都是4個字節(jié)(32位機). 以此類推,指針也有指向它的指針in ...
C語言指針和數(shù)組
#include int main() { /********************************************* * * 指針和數(shù)組: * 定義 ...
c語言 指針與數(shù)組
關(guān)鍵概念: 1.多個不同類型的指針可以對應(yīng)同一個地址: 2.(&p)則是這樣一種運算,返回一個指針,該指針的值是當時聲明p 時開辟的地址,指針的類型是p的類型對應(yīng)的指針類型: 3.(*p)操作 ...
C語言指針和數(shù)組知識總結(jié)(下)
一.數(shù)組指針: 數(shù)組指針就是一個指針,只不過它指向的是一個數(shù)組.可以通過如下方式來定義 typedef int Array[5]; //數(shù)組類型 Array* m; ? ? ?//數(shù)組定義 還有一種更 ...
C語言核心之數(shù)組和指針詳解
指針 相信大家對下面的代碼不陌生: int i=2; int *p; p=&i;這是最簡單的指針應(yīng)用,也是最基本的用法.再來熟悉一下什么是指針:首先指針是一個變量,它保存的并不是平常的數(shù)據(jù),而 ...
指針與數(shù)組的區(qū)別 —— 《C語言深度剖析》讀書心得
原書很多已經(jīng)寫的很清楚很精煉了,我也無謂做無意義的搬運,僅把一些基礎(chǔ)和一些我自己以前容易搞混的地方寫一下. 1. 意義: 指針: 指針也是一種類型,長度為4字節(jié),其存放的內(nèi)容只能是一個地址(4字節(jié)). ...
隨機推薦
Windows和linux的文件共享(1)
今天是我學習linux以來第一次寫博客.帶著一種激動心情我開始嘗試著去完成第一篇博客.從易到難.所以第一次我就主要學習了Windows之間的文件共享. Window之間的文件共享是通過局域網(wǎng)實現(xiàn)的.局 ...
android:persistent屬性
application PhoneApp既沒有被Broadcast喚醒,也沒有被其他service調(diào)用,那么是android是通過什么方式來啟動PhoneApp,所以就發(fā)現(xiàn)了屬性android:per ...
js中的寫出想jquery中的函數(shù)一樣調(diào)用
1.IIFE: Immediately-Invoked function Expression 函數(shù)模塊自調(diào)用 2.代碼實現(xiàn)
unity項目build成webgl時選擇生成目錄(解決方法)
在unity里點擊File>>Build Settings...>>勾選你要生成的Scenes>>選擇webgl>>后面Development Buil ...
docker學習系列(二):使用Dockerfile創(chuàng)建自己的鏡像
dockerfile可以允許我們自己創(chuàng)建鏡像,通過編寫里面的下載軟件命令,執(zhí)行docker build 即可生成鏡像文件. 初嘗dockerfile 新建一個目錄test,然后進入這個目錄,創(chuàng)建一個名 ...
主引導(dǎo)記錄MBR的結(jié)構(gòu)和作用
MBR磁盤分區(qū)都有一個引導(dǎo)扇區(qū),稱為主引導(dǎo)記錄,英文簡稱為MBR.1.?MBR的結(jié)構(gòu)MBR扇區(qū)位于整個硬盤的第一個扇區(qū):按照C/H/S地址描述,即0柱面〇磁頭1扇 區(qū):按照LBA地址描述即0扇區(qū).它是 ...
Scrum Meeting 5 -2014.11.11
放假過掉一大半.大家都努力趕著進度,算法實現(xiàn)基本完成.可能還有些細小的改動,但也可以統(tǒng)一進入測試階段了. 今天叫了部分在校人員開了個小會.任務(wù)決定以測試為主,同時開始進行服務(wù)器的部署. 在之前嘗試服務(wù) ...
vue組件中,iview的modal組件爬坑--modal的顯示與否應(yīng)該是使用v-show
這是我第一次寫博客,主要是記錄下自己解決問題的過程和知識的總結(jié),如有不對的地方歡迎指出來! 需求:點擊btn,彈出modal顯示圖表(以折現(xiàn)圖為例) 這應(yīng)該是很基本的需求也是很容易實現(xiàn)的,代碼和效果如 ...
關(guān)于Android不同系統(tǒng)版本的市場占比情況詳解
一,google官方統(tǒng)計的不同Android版本市場的占比強開 google統(tǒng)計的數(shù)據(jù)情況 這個是google官方對于不同版本的市場占比情況.這個是針對全世界所有的Android手機占比情況. 二,友 ...
總結(jié)
以上是生活随笔為你收集整理的指针c语言与数组,C语言指针与数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 极密宝、Lastpass、1passwo
- 下一篇: rizomuv缩放排布_Unfold 3