久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

C語言中字符串與字符數(shù)組分析

作者:huqin   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2014年03月13日   【字體:

字符串并不是C語言中默認(rèn)存在的類型,但是由于字符串的實用性,在譚浩強C語言中有對字符串的一些描述,但是不是特別的詳細(xì)。有時候?qū)懘a時都不會注意到一些小細(xì)節(jié),本文就結(jié)合實驗分析一下字符串與字符數(shù)組之間的差別。

    字符串與字符數(shù)組的區(qū)別在過去我一直是處于一知半解的狀態(tài),字符串是通常被認(rèn)為是常量,是保存在一段固定的內(nèi)存中的,這段內(nèi)存是以'\0'為結(jié)束符,這段內(nèi)存通常只能通過一個指針來找到。字符數(shù)組其實和其他數(shù)組沒什么區(qū)別,只是保存的數(shù)據(jù)類型是字符類型(char),它沒有強制要求最后的元素是否是'\0'。字符數(shù)組的數(shù)組名是指向第0個字符的指針,而不是指向這個字符串的。這與我前期博客中對數(shù)組的分析結(jié)論是相同的,數(shù)組名并不像指針存在一個地址來保存指針名,數(shù)組名可以看做是匯編程序中的一個標(biāo)號,并沒有專門的地址來保存數(shù)組名。

    但是字符串和字符數(shù)組又有很多相似的地方,特別是當(dāng)我們結(jié)合指針操作字符數(shù)組時候,就會導(dǎo)致錯誤的產(chǎn)生,我覺得只有搞清楚一些概念就能較好的避免這種錯誤的產(chǎn)生。這個概念就是指針就是指針,數(shù)組就是數(shù)組,兩個搞混只是因為某些巧合使我們誤以為指針和數(shù)組是等值的。兩者實質(zhì)上是不相同的。

    字符數(shù)組和字符串的定義如下:

1.                             //字符串

2.                             char *str = "string is a constant";

3.                             //字符數(shù)組

4.                             char strarray[] = {'s','t','r','i','n','g',' ','i','s',' ','a',' ','c','o','n','s','t','a','n','t','\0'};

5.                             //或者

6.                             char strarray[] = "string is a constant";

7.                             char strarray[] = {"string is a constant"};

    其中從上面的定義可以知道字符串實質(zhì)上一塊內(nèi)存,其中保存的值是常量,常量其實就是不能采用程序?qū)?nèi)存中的值進(jìn)行修改,當(dāng)然只是程序不能,我認(rèn)為就像嵌入式C語言中的const類型一樣,雖然我們通常認(rèn)為這個變量是常量,但實質(zhì)上是只讀性變量,只是不能通過程序修改,還可以通過其他的方式修改。這時候str指向的內(nèi)存空間中保存的數(shù)據(jù)是不能被程序修改的,也只能通過str指針對這段內(nèi)存進(jìn)行訪問。

如果字符數(shù)組定義成單個的字符,我們也許還能較好的分別,但如果是如第二種定義、第三種形式定義,我們可能就會產(chǎn)生很大的不理解,這與字符串的類型基本上沒有什么差別,只是多了一個數(shù)組符號[ ],但是這個數(shù)組符號就意味著數(shù)據(jù)類型的改變,我們可以知道數(shù)組中的值是可以改變的,不是常量,說明strarray是一個數(shù)組變量,而str卻是一個字符串常量指針。Strarray是一個標(biāo)號,存儲器中并沒有專門分配內(nèi)存空間存儲strarray的值。但是指針和數(shù)組名很多時候的一些相似性使得我們在處理的時候很難去判斷,比如下面這段代碼:

    char * str = "Constant String";
    char strarray[] = "Constant String";

    int str_len,size_str,array_len,size_array;

    str_len = strlen(str);
    array_len = strlen(strarray);
    size_str = sizeof(str);
    size_array = sizeof(strarray);
    size_str = sizeof(*str);

    如果知道其中的一些數(shù)組與指針的一些區(qū)別可以較好的得到這些值,首先strlen(str)是指求解字符串的長度,但是不包含'\0',因此str_len就是字符串的長度,也就是str_len = 15,array_len也是求解字符串長度的值,我們前面已經(jīng)指出數(shù)組和字符串存在差別,但為什么還可以這樣做呢。我們暫且認(rèn)為包含'\0'的字符數(shù)組可以看做是字符串或者偽字符串,兩者非常的相似,都是存在一段內(nèi)存,保存一段數(shù)據(jù),格式也非常的相似,所以strlen認(rèn)為兩者是相同的,但實質(zhì)上還是存在差別的,但是采用strlen求解字符串長度時,array_len和str_len 是相同的。
    size_str 和size_array這兩個變量的值是我寫這篇文章的初衷,因為我之前根本沒有起分析其中的一些差別,理所當(dāng)然的認(rèn)為兩者是相同的,但細(xì)細(xì)比較發(fā)現(xiàn)兩者確實存在問題。size_str = sizeof(str)的值是多少?sizeof是指對變量或者類型求解存儲空間,是C語言中不被重視的關(guān)鍵字,被大多數(shù)人認(rèn)為是一個函數(shù),實質(zhì)上是一個關(guān)鍵字。這樣我們就能比較快速的確定后面三個變量的值啦,size_str = sizeof(str)是指對str的存儲器長度進(jìn)行計算,str是一個字符型指針,我們知道,指針類型的變量實質(zhì)上就是一個地址,在32機(jī)中,地址通常需要4個字節(jié)的內(nèi)存空間來存儲,因此,size_str = 4;知道了sizeof的意義,size_array就比較簡單了,strarray是一個數(shù)組變量,是一段內(nèi)存空間的標(biāo)示,sizeof(strarray)是指上就是求解數(shù)組的內(nèi)存大小,這時候的內(nèi)存大小包含'\0',因此size_array的值應(yīng)該是15+1=16。而接下來的size_str = sizeof(*str)就更加簡單了,因為我們知道對于字符串指針而言,指向的只是字符串的第0個元素,而不是整個字符串,這時候又會和數(shù)組的數(shù)組名有一定的交叉,數(shù)組的數(shù)組名我們通常被認(rèn)為是一個常量指針(左值右值的差別),也就是指向的起始地址是不變的,但是通常被認(rèn)為是指向數(shù)組首個元素的常指針,不能進(jìn)行++,--操作。接著說明sizeof(*str),*str是指指向字符串的第0個元素的指針的值,也就是說*str是指上就是字符串的第0個元素,也就是一個字符類型,字符類型的大小也就是1字節(jié)了,因此這時候的size_str = 1。
    上面的分析說明了在字符串和數(shù)組的相關(guān)操作中使用strlen的安全性總是比sizeof好,特別是不清楚sizeof的一些意義的情況下。

    通過上面的分析我們應(yīng)該字符串和字符數(shù)組還是存在很多差別的,但是只是理論上的分析,接下來采用程序進(jìn)行測試。這個程序主要檢測字符串是否為常量,而字符數(shù)組是可以修改的。

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>

    #define BUFS 20

    int main()
    {
            char s[] = {"This is just a test!!"};
            char d[] = {"Hello String strncpy!!"};
       
            char *str = "String constant!";
            char *str1 = "Testing!!";
       
            /*不能采用定義指針的情況下就進(jìn)行字符串的操作,
             *需要分配一定長度的空間,
             *因為沒有內(nèi)存空間不能操作
             */
            char *p = malloc(BUFS * sizeof(char));

            /*修改字符數(shù)組*/
            strncpy(p,s,strlen(s));
            printf("p = %s\n",p);
            printf("d = %s\n",d);
            strncpy(d,s,strlen(s));
            printf("d = %s\n",d);
            strncpy(d,s,strlen(d));
            printf("d = %s\n",d);

            /*修改字符串*/
            printf("Test the string constant\n");
            printf("Constant String str = %s\n",str);
       
            strncpy(str,d,strlen(str));
            printf("p = %s\n",p);
            printf("d = %s\n",d);
            strncpy(d,s,strlen(s));
            printf("d = %s\n",d);
            strncpy(d,s,strlen(d));
            printf("d = %s\n",d);

            /*修改字符串*/
            printf("Test the string constant\n");
            printf("Constant String str = %s\n",str);
       
            strncpy(str,d,strlen(str));
            printf("Constant String str = %s\n",str);

            return 0;
    }

編譯以后出現(xiàn)的效果如下:

    [gong@Gong-Computer c_languange]$ gcc -g strncpytest.c -o strncpytest
    [gong@Gong-Computer c_languange]$ ./strncpytest
    p = This is just a
    d = Hello String
    d = This is just a
    d = This is just a
    Test the string constant
    Constant String str = String
    Segmentation fault (core dumped)

結(jié)合上面的代碼可以知道關(guān)于字符數(shù)組的操作都順利的完成了,但是字符串的修改卻沒有正常的完成,出現(xiàn)了
異常(Segmentation fault (core dumped)),實質(zhì)上就是因為字符串是不能修改的,導(dǎo)致了問題的拋出。據(jù)說在ANSI C中規(guī)定對字符串的操作會導(dǎo)致不確定的結(jié)果,這也說明了字符串是不能進(jìn)行修改的。

 

通過上面的分析,數(shù)組和指針還是存在非常大的差別的,在字符串的操作過程中這種差別更加的明顯,因此在實際寫代碼的過程中要時時注意這些小的差別,只有銘記一些概念才能真正的寫好代碼。

 

總結(jié):

字符串是一個常量,不應(yīng)該被修改,修改會出現(xiàn)錯誤,字符數(shù)組可以進(jìn)行修改,因為數(shù)組中的值并不是不變的。在關(guān)于字符串的操作中,最好是采用首先將字符串賦值給字符數(shù)組,然后通過指針的方式訪問進(jìn)行修改等相關(guān)操作,而不能直接對字符串指針進(jìn)行修改操作。

數(shù)組是一段內(nèi)存的標(biāo)示,指針只是保存了一個地址值。

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 中文字幕亚洲精品 | 1级黄色大片 | 亚洲精品色 | 91精产国品一二三区 | 亚洲精品久久久一区二区三区 | 久久精品国产亚洲一区二区 | 一区二区三区国产 | 久久99精品久久久久久秒播九色 | 日韩免费一区二区 | 欧美综合一区 | 久久久久九九九女人毛片 | 黄色大片免费网站 | 操久久 | 午夜影院在线观看 | 国产成人综合久久 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 精品亚洲视频在线 | 99精品久久 | 亚洲一区视频在线 | 亚洲精品在线观 | 久久久精品一区 | 欧美一级欧美三级在线观看 | 免费久久久久久 | 3级毛片 | 国产综合久久 | 久久精品亚洲欧美日韩久久 | 久久国产精品72免费观看 | 日一日操一操 | 一级黄色毛片a | 国产成人福利在线观看 | 亚洲国产一区二区三区 | 久久久久国产精品 | 日本不卡视频在线播放 | 亚洲国产一区视频 | 蜜臀av日日欢夜夜爽一区 | 玖操| 亚洲久草 | 国产欧美一区二区三区免费 | 亚洲播放一区 | 国产一区二区三区在线视频 | 一级毛片免费视频 |