1. 程式人生 > >char * 與char []探究理解

char * 與char []探究理解

nbsp eof 文章 野指針 print 參數 函數 tar 自動

問題引入

以前一直認為二者是一樣的,今天突然發現他們還是有很大的不同的。例如char *a = "abc"和char b[] = "abc",當我使用strcat(b,a)時得到的b是二者的結合,當我使用strcat(a,b)時系統報錯。也就是說前者改變其內容程序是會崩潰的,而後者完全正確。

預備知識

內存分配的三種方式方式:靜態存儲區、堆區和棧區。它們的功能不同,使用方式也就不同。

1.靜態存儲區:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態數據、全局數據和常量。

2.棧區:在執行函數時,函數(包括main函數)內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。(任何變量都處於站區,例如int a[] = {1, 2},變量a處於棧區。數組的內容也存在於棧區。)

3.堆區:亦稱動態內存分配。程序在運行的時候用malloc或new申請任意大小的內存,程序員自己負責在適當的時候用free或delete釋放內存。動態內存的生存期可以由我們決定,如果我們不釋放內存,程序將在最後才釋放掉動態內存。 但是,良好的編程習慣是:如果某動態內存不再使用,需要將其釋放掉,並立即將指針置位NULL,防止產生野指針。

解決問題

回到問題上來,我們來舉個例子:char *a = "Hello",char b[] = "World",其中a是指向字符串第一個字符‘H‘的一個指針,b也是指向字符數組第一個字符‘W‘的指針,但這二者不相同,不同在哪呢?

char *a = "Hello":定義了一個char型的指針a,a在棧上,指向"Hello"所在的內存單元,它不知道這個內存單元有多大。"Hello"存放在常量區,是無法修的。通過指針a只可以訪問字符串常量,而不可以改變它。它在編譯時就會被確定。

char b[] = "World":定義一個字符數組,在棧上開了一塊區域,b為這塊區域的首地址。"World"是存放在這塊區域中,是可以修改的。可以通過指針b去訪問和修改數組內容。它要在運行時才會被確定。

貼段代碼理解一下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
    char *a="Hello";//a在棧上,"Hello"在常數區上
    //a[2]=‘a‘;//系統錯誤:不可以修改常數區數據,只能讀取
char b[]="Hello";//b在棧上,且為字符串"Hello"的首地址 b[2]=a;//可以這樣做,可以修改 char *s1=(char*)malloc(64);//在棧上開辟一個區域放s1,在堆上開辟一個區域,再讓s1指向他 char s2[64]; while(~scanf("%s %s",s1,s2)) { char *s3=s2;//此時s3與s2用法一樣,因為他們指向同一個在棧上的地方 s3[2]=a; printf("%s %s %s\n",s1,s2,s3); } }

結論

在C/C++中,指針和數組在很多地方可以互換使用,這使得我們產生一種錯覺,感覺數組和指針兩者是完全等價的,事實上數組和指針是有很大的區別的。

數組對應著一塊內存區域,而指針是指向一塊內存區域,其地址和容量在生命期裏不會改變,只有數組的內容可以改變;而指針卻不同,它指向的內存區域的大小可以隨時改變,而且當指針指向常量字符串時,它的內容是不可以被修改的,否則在運行時會報錯。

用運算符sizeof可以計算出數組的容量(字節數),而用sizeof卻無法計算指針所指內存的容量,用sizeof(p)得到的結果永遠是4或者2(即指針變量所占內存單元的字節數,一般情況下指針變量占2個或4個字節的內存單元)。在進行參數傳遞時,數組會自動退化為同類型的指針。

在使用過程中,我們可以給char*開辟空間,例如char *s=(char*)malloc(64);這個空間實在堆上的,使用起來就和字符數組很像了(幾乎一樣)

char* 類型使用總結:http://blog.csdn.net/z702143700/article/details/46628251

C語言字符串處理函數:http://www.cnblogs.com/alaigle/archive/2012/05/24/2516062.html

作者: AlvinZH

出處: http://www.cnblogs.com/AlvinZH/

本人Github:https://github.com/Pacsiy/JobDu

本文版權歸作者AlvinZH和博客園所有,歡迎轉載和商用,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

char * 與char []探究理解