【C】 31_字符串典型問題分析

典型問題 一

下面的程序輸出什麼?爲何?
#include <stdio.h>

int main()
{
    char buf[10] = {0};
    char src[] = "hello %s";
    
    snprintf(buf, sizeof(buf), src);
    
    printf("buf = %s\n", buf);
    
    return 0;
}
編譯輸出:
test.c:8: warning: format not a string literal and no format arguments
test.c:8: warning: format not a string literal and no format arguments

運行輸出:
buf = hello ��
  • snprintf 函數自己是可變參數函數,原型以下:

int snprintf(char* buffer, int buf_size, const char* formart, ...)數組

當函數只有 3 個參數時,
若是第三個參數沒有包含格式化信息,函數調用沒有問題;
若是第三個參數包含了格式化信息,但缺乏後續對應參數,則程序行爲不肯定。函數

典型問題 二

  • 下面的程序輸出什麼?爲何?
#include <stdio.h>
#include <string.h>

int main()
{
    #define STR "Hello, \0D.T.software\0"
    
    char* src = STR;
    char buf[255] = {0};
    
    snprintf(buf, sizeof(buf), src);
    
    printf("strlen(STR) = %d\n", strlen(STR));    // 7
    printf("sizeof(STR) = %d\n", sizeof(STR));    // 21 + 1 = 22
    
    printf("strlen(src) = %d\n", strlen(src));    // 7
    printf("sizeof(src) = %d\n", sizeof(src));    // 4
    
    printf("strlen(buf) = %d\n", strlen(buf));    // 7
    printf("sizeof(buf) = %d\n", sizeof(buf));    // 255
    
    printf("src = %s\n", src);                    // Hello, 
    printf("buf = %s\n", buf);                    // Hello, 
}
輸出:
strlen(STR) = 7
sizeof(STR) = 22
strlen(src) = 7
sizeof(src) = 4
strlen(buf) = 7
sizeof(buf) = 255
src = Hello, 
buf = Hello,
  • 字符串相關的函數均以第一個出現的 '0' 做爲結束符
  • 編譯器老是會在字符串字面量的末尾添加 '0'
  • 字符串字面量的本質爲數組

字符串 、 字符數組 、 字符指針 ==> 不一樣優化

典型問題 三

  • 下面的程序輸出什麼?爲何?
#include <stdio.h>
#include <string.h>

int main()
{
    #define S1 "D.T.Software"
    #define S2 "D.T.Software"
    
    if( S1 == S2 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    if( strcmp(S1, S2) == 0 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
}
輸出:【GCC】
Equal
Equal

出乎意料的輸出,字符串是一種特殊的字符數組,在定義時會佔用內存空間,S1 S2 分別爲兩字符串的首元素地址,那麼爲何會有 S1 等於 S2 呢?

GCC的優化:編譯器發現位於只讀存儲區的字符串字面量已經定義,爲了節省空間,就不在進行後續的空間分配,致使S1,S2指向同一個內存空間中的字符串。
  • 字符串之間的相等比較須要使用 strcmp 完成
  • 不能夠直接用 == 進行字符串直接比較 (實質發生的是地址比較)
  • 徹底相同的字符串字面量的 == 比較結果爲false

一些現代編譯可以將相同的字符串字面量映射到同一個無名數組,所以 == 比較結果爲 true。spa

  • 啓示: 爲了得到最高的可移執行性,不編寫依賴特殊編譯器的代碼!!!

典型問題 四

  • 字符串循環右移

void right_shift_r(const char* src, char* result, unsigned int n);指針

函數功能:將輸入字符串 src 循環右移 n 位,result 爲輸出結果
要求: 以效率最高的方式實現
實例:"abcd" --2--> "deabc" | "abcd" --8--> "cdeab"code

#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[(n + i) % 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;
}
輸出:
deabc
abcde
cdeab

圖片描述

以上內容參考狄泰軟件學院系列課程,請你們保護原創!orm

相關文章
相關標籤/搜索