C語言strlen函數(shù)全方位講解
strlen函數(shù)的講解
strlen函數(shù)我們應(yīng)該不陌生,它可以幫助我們求字符串的長度(不包括’\0’),但里面還有一些細(xì)節(jié)需要我們注意??匆幌孪旅孢@張圖:
strlen函數(shù)的頭文件是<string.h>.如果要使用strlen這個(gè)函數(shù),別忘記引頭文件。
字符串是以 ‘\0’ 作為結(jié)束標(biāo)志,strlen函數(shù)返回的是在字符串中 ‘\0’ 前面出現(xiàn)的字符個(gè)數(shù)。以下是用strlen函數(shù)時(shí)可能會(huì)遇到的幾種問題,先看代碼:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "qwer"; char arr2[] = { 'q','w','e','r' }; char arr3[] = { 'q','w','e','r','\0'}; char arr4[10]= { 'q','w','e','r' }; printf("arr1:%d\n", strlen(arr1)); printf("arr2:%d\n", strlen(arr2)); printf("arr2:%d\n", strlen(arr3)); printf("arr2:%d\n", strlen(arr4)); return 0; }
以上代碼輸出的結(jié)果是什么?大家可以先試著算一下。然后再看運(yùn)行結(jié)果。
運(yùn)行結(jié)果如圖所示,arr1初始化的時(shí)候存放的是字符串,字符串的是以’\0’ 為結(jié)束標(biāo)志的,所以arr1的大小為4。這個(gè)應(yīng)該問題不大。
重點(diǎn)說一下下面這幾個(gè)。
arr2:我在初始化arr2的時(shí)候,是對arr2是以字符進(jìn)行初始化的,但是我沒有設(shè)置arr的大小,所以編譯器是不知道arr2的大小的,后面存放的是什么東西也是不知道的,但是strlen它是找’\0’的,并返回’\0’之前字符的個(gè)數(shù)。所以
在strlen找到’\0’之前,前面有36個(gè)字符。
arr3:arr3與arr2不同的是,但是我在最后輸入了’\0’進(jìn)行初始化,所以arr3很簡單的就找到了’\0’,并返回4。
arr4:arr4與arr2不同的是:我這次設(shè)置了arr4的大小,然后我用字符對arr4進(jìn)行了初始化,雖然是用字符進(jìn)行的部分初始化,但是編譯器會(huì)幫我把沒初始化的地方默認(rèn)初始化為0,‘\0’的ASCII碼值就是0,C語言字符在內(nèi)存的形式就是ASCII碼值,所以后面沒初始化的地方存放的都是’\0’。
我們再來看一個(gè)東西,由上面的圖,我們還可以知道strlen的返回值是size_t,這是一個(gè)無符號數(shù)。如果不清楚這個(gè)地方,我們也可能會(huì)在使用strlen的時(shí)候出現(xiàn)一些問題??匆幌孪旅娴拇a:
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") - strlen("qwer") < 0) { printf("1"); } else { printf("0"); } return 0; }
對于上面的代碼的運(yùn)行結(jié)果是什么?
按常理來說,前面的字符串大小為3,后面的為4,比4小應(yīng)該會(huì)打印1。我們來看運(yùn)行結(jié)果:
它的運(yùn)行結(jié)果是0,難道前面的字符串大小比后面的大嗎,其實(shí)不是。關(guān)鍵在于它的返回值是一個(gè)無符號數(shù)。無符號數(shù)只有正數(shù),沒有負(fù)數(shù)。3-4=-1,但是此時(shí)的-1并不是有符號數(shù),而是一個(gè)無符號數(shù),那么-1此時(shí)就是一個(gè)很大的正數(shù)。所以此時(shí)才會(huì)輸出0
如果要解決這個(gè)問題,有以下兩種解決方案:
方法1:不相減,進(jìn)行比較:
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") < strlen("qwer")) { printf("1"); } else { printf("0"); } return 0; }
方法2:強(qiáng)制類型轉(zhuǎn)換
#include<stdio.h> #include<string.h> int main() { if ((int)strlen("abc") -(int)strlen("qwer") < 0) { printf("1"); } else { printf("0"); } return 0; }
說一下方法1,無符號數(shù)只有正數(shù),沒有負(fù)數(shù),直接計(jì)算大?。ㄕ龜?shù))就可以直接比較了。方法2是強(qiáng)制轉(zhuǎn)換為int類型的數(shù)據(jù),整型是有符號數(shù),有符號數(shù)就可以進(jìn)行相減,結(jié)果為-1,就是-1。兩種結(jié)果輸出結(jié)果都是1.
strlen函數(shù)的模擬實(shí)現(xiàn)
講完了strlen函要注意的問題,下面講一下strlen函數(shù)的模擬實(shí)現(xiàn)??偣灿腥N方法:計(jì)數(shù)器方式,遞歸的方式和指針-指針的方式。
計(jì)數(shù)器方式
實(shí)現(xiàn)的思想:設(shè)置一個(gè)計(jì)數(shù)的變量,讓一個(gè)字符指針遍歷字符數(shù)組的每一個(gè)元素,如果指針指向的元素不是’\0’,計(jì)算器就自增,直到指針指向的元素是’\0’,就停止遍歷,并返回計(jì)數(shù)器。
因?yàn)槭悄M實(shí)現(xiàn),我們就只求一致,返回值就設(shè)置為size_t。
實(shí)現(xiàn)代碼如下:
#include<stdio.h> #include<string.h> #include<assert.h> size_t my_strlen(const char* p) { int count = 0; assert(p != NULL);//如果等于空指針就會(huì)報(bào)錯(cuò) while((*p) != '\0') { count++; p++; } return count; } int main() { char arr[] = "CSDN"; int ret = my_strlen(arr); printf("%d", ret); return 0; }
遞歸的方式
代碼實(shí)現(xiàn)的思想:這種方式是不用創(chuàng)建臨時(shí)變量的一種方法, 只使用指針進(jìn)行遍歷,如果指針指向的不是’\0’,那么就返回1和指針指向后一個(gè)數(shù)據(jù)的結(jié)果。
size_t my_strlen(const char* p) { if ((*p) == '\0') { return 0; } else { return 1 + my_strlen(p+1); } } int main() { char arr[] = "CSDN"; int ret = my_strlen(arr); printf("%d", ret); return 0; }
指針減指針的方式
代碼實(shí)現(xiàn)的思想:
元素名是首元素的地址,我們就在定義一個(gè)指針,指向這個(gè)數(shù)組,讓這個(gè)指針進(jìn)行遍歷,指向的不是’\0’就讓指針進(jìn)行自增。最后讓遍歷完數(shù)組的指針減去數(shù)組名(也就是首元素的地址)。
注意:當(dāng)兩個(gè)指著指向同一塊空間時(shí),指針減指針的絕對值就是兩個(gè)指針之間的元素個(gè)數(shù),而不是 個(gè)數(shù)*數(shù)據(jù)類型所占的空間。
size_t my_strlen(const char* p) { char* s = p; while((*s) != '\0') { s++; } return s - p; } int main() { char arr[] = "CSDN"; int ret = my_strlen(arr); printf("%d", ret); return 0; }
到此這篇關(guān)于C語言strlen函數(shù)全方位講解的文章就介紹到這了,更多相關(guān)C語言strlen函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(13.羅馬數(shù)字轉(zhuǎn)化成整數(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(13.羅馬數(shù)字轉(zhuǎn)化成整數(shù)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++課程設(shè)計(jì)之學(xué)生成績管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++課程設(shè)計(jì)之學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12C++類中的常數(shù)據(jù)成員與靜態(tài)數(shù)據(jù)成員之間的區(qū)別
常數(shù)據(jù)成員是指在類中定義的不能修改其值的一些數(shù)據(jù)成員,類似于我們以前學(xué)過的常變量,雖然是變量,也有自己的地址,但是一經(jīng)賦初值,便不能再被修改2013-10-10C/C++實(shí)現(xiàn)string和int相互轉(zhuǎn)換的常用方法總結(jié)
在C++編程中,經(jīng)常需要在字符串(string)和整型(int)之間進(jìn)行轉(zhuǎn)換,本文將詳細(xì)介紹幾種在C和C++中實(shí)現(xiàn)這兩種類型轉(zhuǎn)換的常用方法,有需要的可以參考下2024-01-01C語言中計(jì)算函數(shù)執(zhí)行時(shí)間的三種方式
本文主要介紹了C語言中計(jì)算函數(shù)執(zhí)行時(shí)間的三種方式,主要包括clock(),timeb和time,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09