成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

C之典型字符串(二十八)

        我們在上節(jié)博客中介紹了 C 語言中字符串相關(guān)的概念,那么我們今天就來看看在字符串這塊的典型問題。

開魯網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,開魯網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為開魯千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的開魯做網(wǎng)站的公司定做!

        A、我們先來看看下面的示例代碼會輸出什么,代碼如下

#include <stdio.h>

int main()
{
    char buf[15] = {0};
    char src[] = "hello %s";
    
    snprintf(buf, sizeof(buf), src);
    
    printf("buf = %s\n", buf);
    
    return 0;
}

        我們先來說說 snprintf 函數(shù),它本身是可變參數(shù)的函數(shù),原型是這樣的:int snprintf(char* buf, int buf_size, const char* fomart, ...)。當(dāng)函數(shù)只有3個參數(shù)時,如果第三個參數(shù)沒有包含格式化信息,函數(shù)調(diào)用沒有問題;相反,如果第三個參數(shù)包含了格式化信息,但缺少后續(xù)對應(yīng)參數(shù),則程序行為不穩(wěn)定。上面的程序中第8行調(diào)用了 snprintf 函數(shù),但是在第6行定義的 src 字符數(shù)組中包含了 %s,則它的行為是不確定的。我們來看看編譯結(jié)果C之典型字符串(二十八)

        我們看到編譯其實(shí)已經(jīng)提示了,打印的結(jié)果果然是不確定的。那么我們在 snprintf 函數(shù)中再加上第四個參數(shù)字符串“world”試試(或者直接把第6行后面的 %s 變成 world 也是同樣的效果)。編譯結(jié)果如下

C之典型字符串(二十八)

        那么我們看到編譯沒有警告,程序也完美運(yùn)行。

        B、我們再來看看下面這份示例代碼

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

int main()
{
    #define STR "Hello, \0World\0"
    
    char* src = STR;
    char buf[255] = {0};
    
    snprintf(buf, sizeof(buf), src);
    
    printf("strlen(STR) = %d\n", strlen(STR));
    printf("sizeof(STR) = %d\n", sizeof(STR));
    
    printf("strlen(src) = %d\n", strlen(src));
    printf("sizeof(src) = %d\n", sizeof(src));
    
    printf("strlen(buf) = %d\n", strlen(buf));
    printf("sizeof(buf) = %d\n", sizeof(buf));
    
    printf("src = %s\n", src);
    printf("buf = %s\n", buf);
    
    return 0;
}

        我們先來分析下這個程序,第6行定義了一個宏,但是它里面有兩個 \0,實(shí)際上是3個,因?yàn)榫幾g器還會為字符串自動去分配個 \0。在程序的第11行進(jìn)行 src 到 buf 的內(nèi)容復(fù)制。我們在上屆說過字符數(shù)組是以 \0 結(jié)尾的,因此第13行打印的長度為7。但第14行打印的是它整個宏定義的長度,所以為15。第16行打印的也便是 7 了,第17行打印的指針的長度,便是4。第19行打印的 buf 中內(nèi)容的長度同樣也是 7,第20行打印的 數(shù)組 buf 的長度便是 255。第22和23行分別打印 src 和 buf 中的內(nèi)容,便是 hello 了。我們來看看編譯結(jié)果C之典型字符串(二十八)

        結(jié)果和我們分析的一致,字符串字面量的本質(zhì)為數(shù)組。

        C、再來看第三個示例程序,代碼如下

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

int main()
{
    #define s1 "hello world"
    #define s2 "hello world"
    
    if( s1 == s2 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    if( strcmp(s1, s2) == 0)
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    return 0;
}

        我們先來分析下,我們在第6和7行分別定義了兩個宏字符串(但是它們的內(nèi)容是相同的)。接下來我們直接將 s1 和 s2 進(jìn)行判斷是否相等。那么在這塊我們判斷的應(yīng)當(dāng)是他兩的地址,它們在這塊就是數(shù)組,兩個數(shù)組怎么可能進(jìn)行相等比較呢。如果是判斷地址,第一個 if 語句應(yīng)當(dāng)打印出不相等的。下面的 if 語句是用 strcmp 函數(shù)進(jìn)行判斷的餓,那么這個當(dāng)然是相等的啦,因?yàn)檫@個函數(shù)判斷的是他兩的內(nèi)容。所以經(jīng)我們分析,第一個 if 語句打印出 Non Equal,第二個 if 語句打印出 Equal。我們來看看編譯器就是是怎么處理的

C之典型字符串(二十八)

        我們看到第一個和我們分析的不一樣,那么我們再來看看 BCC 編譯器

C之典型字符串(二十八)

        那么 BCC 編譯器的結(jié)果和我們分析的是一致的。在 gcc 編譯器中它做了優(yōu)化,當(dāng)我們定義 s1 之后,進(jìn)行 s2 的定義時。編譯器發(fā)現(xiàn)他倆內(nèi)容是一樣的,便將 s2 也指向了 s1 的地址,因?yàn)樗X得你是在浪費(fèi)內(nèi)存。我們在程序中加上打印 s1 和 s2 的地址的語句,gcc 打印結(jié)果如下

C之典型字符串(二十八)

        gcc 編譯器果然是將他倆放在一個地址上了。但是我們看看 BCC 呢

C之典型字符串(二十八)

        我們看到 BCC 是這樣的,所以我們在以后不能寫出依賴于某種編譯器的代碼,這樣的話,代碼的可移植性就降低了。所以我們在進(jìn)行字符串之間的相等比較時需要用 strcmp 完成,不可直接用 == 進(jìn)行字符串直接進(jìn)行比較。完全相同的媳婦吃字面量的 == 比較結(jié)果為 false。一些現(xiàn)代編譯器能夠?qū)⑾嗤淖址置媪坑成涞酵粋€無名字符數(shù)組,因此 == 比較結(jié)果為 true。

        D、最后我們再來看個關(guān)于字符串循環(huán)右移的問題,這也是一道筆試面試題。代碼如下

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

void right_shift_r(const char* src, char* result, unsigned int n)
{
    const unsigned int len = strlen(src);
    int i = 0;
    
    for(i=0; i<len; i++)
    {
        result[(i+n) % len] = src[i];
    }
    
    result[len] = '\0';
}

int main()
{
    char result[255] = {0};
    
    right_shift_r("abcde", result, 2);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 5);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 8);
    
    printf("%s\n", result);
    
    return 0;
}

        我們可以利用求余的的方式進(jìn)行字符串的賦值。那么我們用一個 for 循環(huán)就完成右移,它的時間復(fù)雜度為 O(n),這個效率無疑是最高的。

        歡迎大家一起來學(xué)習(xí) C 語言,可以加我QQ:243343083。

當(dāng)前標(biāo)題:C之典型字符串(二十八)
網(wǎng)頁路徑:http://jinyejixie.com/article28/poescp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站營銷、網(wǎng)站設(shè)計(jì)網(wǎng)站維護(hù)、自適應(yīng)網(wǎng)站做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營
炎陵县| 大安市| 九龙县| 叙永县| 肥西县| 抚州市| 海南省| 泸溪县| 远安县| 平和县| 盐城市| 康保县| 库尔勒市| 灵丘县| 抚顺市| 新河县| 洛川县| 泾源县| 英山县| 龙泉市| 北京市| 乐陵市| 壶关县| 资溪县| 宜川县| 阿拉善左旗| 塘沽区| 漳浦县| 沙洋县| 新龙县| 丹寨县| 焉耆| 察哈| 江都市| 青阳县| 瑞昌市| 莱西市| 东港市| 乌鲁木齐县| 鸡泽县| 桃园市|