浅谈C/C++中的指针和数组(一)
??????指針是C/C++的精華,而指針和數(shù)組又是一對歡喜冤家,很多時候我們并不能很好的區(qū)分指針和數(shù)組,對于剛畢業(yè)的計算機系的本科生很少有人能夠熟練掌握指針以及數(shù)組的用法和區(qū)別。造成這種原因可能跟現(xiàn)在大學教學以及現(xiàn)在市面上流行的很多C或者C++教程有關,這些教程雖然通俗易懂,但是在很多關鍵性的地方卻避而不談或者根本闡述不清楚,甚至很多時候闡述的是錯誤的觀點。一般最初學習C/C++的時候接觸到的都是這類教程,學習效果可想而知。對于初學者選擇好的教程真的很關鍵,因為先入為主,一旦你接受了錯誤的觀點或者思想即使后來知道了也一時很難糾正過來(我是深有體會),在此我推薦三本很適合于初學者的教程:
?????? 《The C Programming Language》Brian W. Kernighan和Dennis M. Ritchie的經(jīng)典著作(K&R圣經(jīng))
???????《C ++ Primer》Stanley?B.?Lippman, Josée?Lajoie, Barbara?E.?Moo?C++經(jīng)典權威著作
???????《Pointers on C》Kenneth A.Reek
??????很多時候,會有人說“指著和數(shù)組是相同的”,這是一種非常危險的說法,并不完全正確。在一定的上下文環(huán)境中,指針和數(shù)組是等同的,并非所有情況下如此。然而人們很多時候卻自然而然忽略了這種情況成立的條件,去假定所有情況下都是如此。下面著重談一下指針和數(shù)組的區(qū)別。
一.指針和數(shù)組的定義
??? 指針是指針,指針變量存儲的是一個地址,用來間接訪問數(shù)據(jù),在32位系統(tǒng)下,一個指針變量(包括void指針)一般占4個字節(jié)的空間(有的編譯器是占2個字節(jié))。指針可以指向任何內(nèi)存空間,但不是任何內(nèi)存空間都可以通過指針去訪問。
??? 數(shù)組是數(shù)組,定義一個數(shù)組之后,編譯器便根據(jù)該數(shù)組元素的類型和個數(shù)在內(nèi)存開辟一段連續(xù)的空間來存放數(shù)據(jù),從而直接訪問數(shù)據(jù)。
??? 下面看一個例子
??? 在file1.c中有如下代碼:
char p[100]="abcdef";??? 在file2.c中有如下代碼:
#include<stdio.h>extern char *p;int main(void) {printf("%c\n",p[1]);return 0; }??? 發(fā)現(xiàn)能夠編譯通過,但是能正確執(zhí)行么?調試發(fā)現(xiàn):出現(xiàn)下圖這個錯誤,無法計算得到p[1]的值。原因稍后作解釋。
從這里就可以看出,指針和數(shù)組并不是等同的,數(shù)組的定義并不等同于指針的外部聲明(注意聲明和定義的區(qū)別,定義是為一個變量或者對象分配內(nèi)存空間,而聲明只是描述類型)。
二.指針和數(shù)組訪問時的區(qū)別
???? 對數(shù)組下標的引用:
???? 對指針的引用:
從上面的圖中可以看出,指針和數(shù)組根本就是兩個完全不一樣的東西。對于數(shù)組,由于編譯器在編譯的時候就已經(jīng)知道每個符號的地址,因此如果需要一個地址來執(zhí)行某種操作,可以直接進行操作,并不需要增加指令首先取得具體地址,對于數(shù)組就是如此;而對于指針,必須在運行時首先取得它當前的具體值然后才能進行引用。從這點就可以解釋為什么上面的程序無法正確執(zhí)行,因為在file1.c中定義的p是一個數(shù)組,而在file2.c中卻聲明的是一個指針。因此在file2.c中引用時默認p是一個指針變量,并且會把指針變量中的任何數(shù)據(jù)當做地址來處理,因此首先取原數(shù)組的前4個字節(jié)的內(nèi)容:0x61 0x62 0x63 0x64構成一個地址(暫不考慮大小端的問題)0x61626364,然后按照char型讀取0x61626364這個地址中的內(nèi)容,但是這個地址可能并不是有效地地址,即使是有效地,也不是我們想要的。大家可以想一下如果在file1.c中將p定義為指針類型,而在file2.c中將p聲明為數(shù)組類型,會是什么情況?
解決上述問題的辦法就是在任何時候保持定義和聲明一致。
測試程序:
file2.c
#include<stdio.h>extern char p[]; extern void print();int main(void) {printf("%x\n",p[0]);printf("%x\n",p[1]);printf("%08x\n",p); //注意此時p的值是存儲原指針p(file1.c中的p)的內(nèi)存單元的首地址 print();return 0; }file1.c
#include<stdio.h> char *p="abcdef";void print() {printf("%08x\n",p);printf("%08x\n",&p); }執(zhí)行結果為:
28
20
00424a30
00424a30
00422028
00424a30
Press any key to continue
三.一些應該注意的地方
?? 1.sizeof計算所占空間時的區(qū)別。
????? 對于數(shù)組,sizeof計算的是整個數(shù)組所占的空間,而在32位系統(tǒng)下,sizeof 指針的值始終為4.
?? 2.數(shù)組名作為左值時不能被修改,而指針作為左值時可以被賦值。
?? 3.指針可以進行自增(自減)運算(void指針除外,因為void指針無法知道步長),但是數(shù)組不能進行自增或者自減運算。
?? 4.理解char *p="abcde"和char str[]="abcde"的區(qū)別。
總結
以上是生活随笔為你收集整理的浅谈C/C++中的指针和数组(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科目二、科目三易挂项目整理和网友支招
- 下一篇: C++中重载与重写函数区别及虚函数(转载