C語言對字符串的處理

2021-12-31 JTLinux
一、浮點數和0的比較

無論是 float 還是 double 類型的變量,都有精度限制。所以一定要避免將浮點變量 用「= =」 或 「=」與數字比較,應該設法轉化成「>=」或「<=」形式。 if="" x="">=-EPSINON) && (x<=EPSINON))其中 EPSINON 是允許的誤差(即精度)。

float a = 0.1;

if (a * 10 >= 1.0 - 0.0000001 && a * 10 <= 1.0 + 0.000001)

{

        printf("==");

}

else

{

        printf("x");

}

二、小寫字母轉大寫字母1.ASSIC碼的辦法

#include

void main() {

        char a;

        printf(「請輸入一個大寫字母:」);

        scanf("%c", &a);

        printf("\n它對應的大寫字母是:%c\n", a + 32);

}

2.庫函數

#include

#include

int main()

{

        char s[] = "gasdgasSFASFAS";

        int i;

        printf("befor toupper :%s\n", s);

        for (i = 0; i < sizeof(s); i++)

        {

                s[i] = toupper(s[i]);

        }

        printf("after toupper :%s\n", s);

       

}

三、C語言字符數組和字符指針梳理1.數組退化成指針

#include

int size(char a[10])

{

        return sizeof(a);

}

int main(void)

{

        char a[] = { 'C','h','i','n','a','\0' };

        char* p = "China";

        char* q = a;

        printf("sizeof(a)=%d\n", sizeof(a));  //sizeof(a)=6

        printf("sizeof(p)=%d\n", sizeof(p));  //sizeof(p)=4

        printf("sizeof(q)=%d\n", sizeof(q));  //sizeof(q)=4

        printf("size(a)=%d\n", size(a));      //size(a)=4

        return 0;

}

首先C語言裡面不支持數組作為形參來進行調用,例如上述函數int size(char a[])實際上在進行編譯時,是作為指針來處理的,所以上面的函數完全等價於int size(char *a);所以上面printf("size(a)=%d\n", size(a));  輸出size(a)=4。

數組作為參數傳給函數時,傳的是指針而不是數組,傳遞的是數組的首地址,如 fun (char[8]),fun(char [])都等價於 fun(char*)。

退化為指針;需要數組大小時,需要一個參數傳數組名,另一個傳數組大小:void fun(int* a, size_t n);

2.僅在以下3種情況中,數組不會退化成指針

sizeof是一個關鍵字並不是一個函數。

使用sizeof(a)的時候,所以上面sizeof(a)的結果為6位元組。

對數組名取地址操作:&a。&a的類型為pointer to array of 6 chars,而對字符串指針取地址結果為pointer to pointer to char。

使用字符串初始化數組的時候也不會退化。

3.其它情況都會退化成「指向數組首元素的指針」,比如

組名做函數參數時,a都會退化成&a[0]指針。如上面的size函數和printf函數中的a[]都是這種情況。

二維數組,char s[10][8]數組的首元素(得理解這個首元素,從一維數組的角度看的)是一維數組s[0],因此退化成&s[0]指針。

4.數組定義字符串和指針定義字符串的區別

使用數字定義的字符串只分配字符串所需的空間(上例中為6個字節),數字名沒有單獨的存儲空間;使用指針定義字符串,除了字符串佔用的空間,還要為指針變量分配對應的空間。

數組退化成指針為「常量指針」,不可更改,而直接指向字符串的指針可修改,如:

char a[10] = "China";

const char* p = "China";

a++;   // 錯誤的

p++;   // 正確的

5.C語言字符串指針(指向字符串的指針)

C語言中沒有特定的字符串類型,我們通常是將字符串放在一個字符數組中。如下代碼:

#include

#include

int main() {

        char str[] = "http://c.biancheng.net";

        int len = strlen(str), i;

        //直接輸出字符串

        printf("%s\n", str);

        //每次輸出一個字符

        for (i = 0; i < len; i++) {

                printf("%c", str[i]);

        }

        printf("\n");

        return 0;

}

運行結果:

http://c.biancheng.net
http://c.biancheng.net

字符數組當然是數組,那麼我們就可以利用指針對字符數組進行操作。

#include

#include

int main() {

        char str[] = "http://c.biancheng.net";

        char* pstr = str;

        int len = strlen(str), i;

        //使用*(pstr+i)

        for (i = 0; i < len; i++) {

                printf("%c", *(pstr + i));

        }

        printf("\n");

        //使用pstr[i]

        for (i = 0; i < len; i++) {

                printf("%c", pstr[i]);

        }

        printf("\n");

        //使用*(str+i)

        for (i = 0; i < len; i++) {

                printf("%c", *(str + i));

        }

        printf("\n");

        return 0;

}

運行結果:

http://c.biancheng.net
http://c.biancheng.net
http://c.biancheng.net

除了字符數組以外,c語言還支持另外一種表示字符的方法,就是直接使用一個指針指向字符串,例如:

char *str = "http://c.biancheng.net";

或者:

char *str;

str = "http://c.biancheng.net";

 

下面演示如何輸出這種字符串:

#include

#include

int main()

{

        char a[] = "fjasdifaisdhfg";

        printf("%d\n", &a);

       

}

#include

#include

int main() {

        char* str = "http://c.biancheng.net";

        int len = strlen(str), i;

        //直接輸出字符串

        printf("%s\n", str);

        //使用*(str+i)

        for (i = 0; i < len; i++) {

                printf("%c", *(str + i));

        }

        printf("\n");

        //使用str[i]

        for (i = 0; i < len; i++) {

                printf("%c", str[i]);

        }

        printf("\n");

        return 0;

}

運行結果:

運行結果:
http://c.biancheng.net
http://c.biancheng.net
http://c.biancheng.net

這樣看起來,字符數組和使用一個指針指向字符串是非常相似的。那麼這兩種表示字符串的區別是什麼?

特別注意:

字符數組和指針字符串的區別是內存中的存儲區域不一樣,字符數組存儲在全局數據區或棧區,指針字符串存儲在常量區。

全局區和棧區的字符串(包括其它數據)有讀取和寫入的權限,而常量區的字符串只有讀取權限,沒有寫入權限。

  內存權限不同導致一個明顯的結果就是,字符數組在定義後可以讀取和修改每個字符,而對於指針字符串來說,一旦被定義

後就只能讀取而不能修改,任何對它的賦值都是錯誤的。

#include

int main() {

        char* str = "Hello World!";

        str = "I love C!";  //正確

        str[3] = 'P';  //錯誤

        return 0;

}

這段代碼能夠正常編譯和連結,但是在運行時會出現段錯誤(Segment Fault)或者寫入錯誤。

第四行代碼是正確的,可以更改指針變量本身的指向;第5行代碼是錯誤的,不能修改字符串中的字符。

 那麼到底使用字符數組還是字符串常量?

在編程過程中,如果只涉及到對字符串的讀取,那麼字符數組和字符串常量都可以滿足要求;如果有寫入(修改)的操作,

那麼只能使用字符數組,不能使用字符串常量。

獲取用戶輸入的字符串就是一個典型的寫入操作,只能使用字符數組,不能使用字符串常量,請看下面的代碼:

#include

int main() {

        char str[30];

        gets(str);

        char* ptr;

        gets(ptr);//錯誤

        printf("%s\n", str);

        return 0;

}

四、Memcpy()和memcpy_s()的用法

1、memcpy()函數

原型:extern void *memcpy(void *dest, void *src, unsigned int count);

用法:#include "string.h"

功能:由src所指向內存區域複製count個字節到dest指向的內存區域。

返回值:函數返回指向dest的指針

注意:src和dest所指向的內存區域不能重疊

如果目標內存區域dest已有數據,執行memcp後,將覆蓋count個字節的原有數據。

memcpy的操作對象不局限於某一類數據類型,只要能給出對象的其實地址和內存長度信息,並且對象具有可操作性即可。

 

2、memcpy_s()函數

原型:errno_t memcpy_s(

             void *dest,

             size_t numberOfElements,

             const void *src,

             size_t count

);

參數說明:

dest: 目標地址

numberOfElements: 目標dest的size

src: 源地址

count: 要複製的字節數

注意:要保證numberOfElements >= count。

返回值:成功時返回0,錯誤返回非零值。

五、進程線程間的通信

1、消息隊列,是最常用的一種,也是最靈活的一種,通過自定義數據結構,可以傳輸複雜和簡單的數據結構。

在Windows程序設計中,每一個線程都可以擁有自己的消息隊列(UI線程默認自帶消息隊列和消息循環,工作線程需要手動實現消息循環),因此可以採用消息進行線程間通信sendMessage,postMessage。

定義消息#define WM_THREAD_SENDMSG=WM_USER+20;

添加消息函數聲明afx_msg int OnTSendmsg();

添加消息映射ON_MESSAGE(WM_THREAD_SENDMSG,OnTSM)

添加OnTSM()的實現函數;

在線程函數中添加PostMessage消息Post函數

2、使用全局變量

進程中的線程間內存共享,這是比較常用的通信方式和交互方式。

註:定義全局變量時最好使用volatile來定義,以防編譯器對此變量進行優化。

3、使用事件CEvent類實現線程間通信

Event對象有兩種狀態:有信號和無信號,線程可以監視處於有信號狀態的事件,以便在適當的時候執行對事件的操作。

1)創建一個CEvent類的對象:CEvent threadStart;它默認處在未通信狀態;

2)threadStart.SetEvent();使其處於通信狀態;

3)調用WaitForSingleObject()來監視CEvent對象

六、多態

#include

using namespace std;

class Shape {

protected:

        int width, height;

public:

        Shape(int a = 0, int b = 0)

        {

                width = a;

                height = b;

        }

        virtual int area()

        {

                cout <<< span=""> "Parent class area :" <<< span=""> endl;

                return 0;

        }

};

class Rectangle : public Shape {

public:

        Rectangle(int a = 0, int b = 0) :Shape(a, b) { }

        int area()

        {

                cout <<< span=""> "Rectangle class area :" <<< span=""> endl;

                return (width * height);

        }

};

class Triangle : public Shape {

public:

        Triangle(int a = 0, int b = 0) :Shape(a, b) { }

        int area()

        {

                cout <<< span=""> "Triangle class area :" <<< span=""> endl;

                return (width * height / 2);

        }

};

// 程序的主函數

int main()

{

        Shape* shape;

        Rectangle rec(10, 7);

        Triangle  tri(10, 5);

        // 存儲矩形的地址

        shape = &rec;

        // 調用矩形的求面積函數 area

        shape->area();

        // 存儲三角形的地址

        shape = &tri;

        // 調用三角形的求面積函數 area

        shape->area();

        return 0;

}

相關焦點

  • C語言字符數組和字符串
    字符數組的各個元素依次存放字符串的各字符,字符數組的數組 名代表該數組的首地址,這為處理字符串中個別字符和引用整個字符串提供了極大的方便。一、字符數組字符數組的定義形式與前面介紹的數值數組相同。例如: 字符數組也允許在定義時進行初始化賦值。
  • C語言字符數組與字符串的使用詳解
    2、字符數組與字符串在c語言中,將字符串作為字符數組來處理。(c++中不是)在實際應用中人們關心的是有效字符串的長度而不是字符數組的長度,例如,定義一個字符數組長度為100,而實際有效字符只有40個,為了測定字符串的實際長度,C語言規定了一個「字符串結束標誌」,以字符'\0'代表。
  • c語言如何查找字符串指定字符
    c語言查找字符串指定字符的方法:1、【strchr()】用來查找某字符在字符串中首次出現的位置;2、【strrchr()】函數用於查找某字符在字符串中最後一次出現的位置
  • C語言中字符串的結束標誌是什麼
    C語言中字符串的結束標誌是【'\0'】。C語言中沒有專門的字符串變量,通常用一個字符數組來存放一個字符串,字符串總是以【'\0'】作為結束符。
  • C語言字符串處理函數之字符串轉換、查詢函數
    介紹完字符串整體操作函數,就該到字符串查詢函數和字符串轉換函數了,至於一些字符串轉換函數,如atoi(),atof(),strtod(),strtol(),tolower(),toupper()等,以後有時間再整理整理。
  • C 語言實現動態字符串
    其他語言中的字符串類型通常在存儲字符串本身時也保存了字符串長度,如Pascal,這樣做的好處是字符串也可以以空字符'\0'結尾,但也會產生緩衝區溢出錯誤,本文實現了一個簡單的動態字符串庫,首先考慮一下,採用什麼樣的數據結構可以避免緩衝區溢出問題呢,為簡化起見,我們定義「字符串」為內存中無類型的字節流,因此可以避開本地化和Unicode等概念
  • c語言字符串 數字轉換函數大全
    float c;     c=atof(a)+atof(b);     printf(「c=%.2f\n」,c);     }執行 c=-98.23atoi(將字符串轉換成整型數)相關函數 atof,atol,atrtod,strtol,strtoul
  • C語言:優雅的字符串函數庫
    以學習一門語言為例:大多數人都持有一種觀念,要真正學好一門語言必須得去所學語言當地學習或生活一段時間。而事實上,大多數人都沒有這樣的學習條件。例如:用新語言寫代碼注釋 / commit message / README / issue;對了,我作為英文的愛好者,一直想重啟我的英文學習之路,後續想在公眾號裡記錄一些英文相關的知識,請你們不要笑話我~~~二、字符串函數庫:Simple
  • 【C語言更新】C語言中字符串的操作
    void  *memset(void *str, int c, size_t n)複製字符  c(一個無符號字符)到參數 str 所指向的字符串的前 n 個字符。char  *strcat(char *dest, const char *src)把 src 所指向的字符串追加到 dest 所指向的字符串的結尾。
  • php字符串常用處理,運算符和幾個常用的字符串函數
    本篇將介紹php字符串常用處理,運算符和幾個常用的字符串函數。有興趣的朋友可以了解一下!php是一門很受歡迎的程式語言之一,由於它的語法簡單易學,迎來了一大批的自學者,小編就是其中一個。php確實相當於其它語言(java、c#等等)比較簡單,但是對一個毫無程式語言基礎的人來說,還是有一定難度的。
  • 在C語言常見的處理字符串函數分別有哪些?
    常見的處理字符串函數有如下:1、strcpy函數:先定義兩個字符數組,分別代表s1和s2,則:strcpy(s1,s2);
  • C/C++中字符串常量的不相等性及字符串的Copy
    ,但在c/c++卻不是這樣。  答案在這裡:因為字符串常量存儲在計算機內存中,兩個字符串常量的地址均不相同,所以這樣的比較自然就不會得到我們所需要的結果,如果要進行是否相等的比較應該使用strcmp()這個涵數進行比較!
  • 在C語言中如何高效地複製和連接字符串?
    就目前而言,在編程領域中,C語言的運用非常之多,它兼顧了高級語言的彙編語言的優點,相較於其它程式語言具有較大優勢。作者 | Martin Sebor譯者 | 蘇本如,責編 | 劉靜以下為譯文:在所有標準C語言<string.h>頭文件中聲明的字符串處理函數中,最常用的是那些用來複製和連接字符串的函數。
  • 【開源共享】拿來即用的C語言字符串函數庫
    一、字符串函數庫:Simple Dynamic Strings1. 簡介Simple Dynamic Strings (簡稱 SDS) 是一個 C 語言字符串庫,它增強了 C 語言字符串處理的能力。printf 直接就可以列印 sds,這就是說 sds 本身就是 C 語言的字符串類型。
  • Golang語言之字符串操作
    %o八進位整數%b二進位整數%f,%g,%e浮點數%t布爾值%c字符%s字符串%q帶雙引號的字符串%v內置格式內容%T類型%p內存地址%%字符%\n換行\t縮進文章內容主要以代碼注釋講解相關知識點如有紕漏,後續會在「Go 語言研究院」https://www.golanghub.cn 修正。如果文章對您有所幫助,還請關注公眾號給予支持。
  • Golang 語言怎麼高效拼接字符串?
    01 介紹在程式語言中,字符串是一種重要的數據結構。在 Golang 語言中,因為字符串只能被訪問,不能被修改,所以,如果我們在 Golang 語言中進行字符串拼接操作,Golang 需要進行內存拷貝。如果讀者朋友們了解過 Golang 語言內存管理的相關知識,就會知道內存拷貝會帶來性能消耗。
  • c語言指針與字符數組
    我們所說的字符串就是字符數組的一種,就如我們常見的"hello world!",字符串的使用在C語言中也是非常重要的,常常會遇到一些操作,如字符串的修改、拷貝、字符串長度等,在物聯網的應用中也尤為突出,物聯網應用中所用的模組,大多是需要使用AT指令的,這就需要對字符串的操作。
  • C語言實現將字符串轉換為數字的方法
    這篇文章主要介紹了C語言實現將字符串轉換為數字的方法,涉及系統函數atoi()函數的使用技巧,需要的朋友可以參考下本文實例講述了C語言實現將字符串轉換為數字的方法。
  • R語言字符串函數詳解
    ", dotall = TRUE))4. str_c 連接字符串str_c(…, sep = 「」, collapse = NULL)str_join(…, sep = 「」, collapse = NULL)str_c("Letter: ", letters[1:5]) str_c("Letter", letters[1
  • C語言 | 將數字轉為字符串
    收錄於話題 #小林C語言源碼 「要成為絕世高手,並非一朝一夕,除非是天生武學奇才,但是這種人…萬中無一」這道理放在