?? 歡迎大家來到貝蒂大講堂??
????養(yǎng)成好習慣,先贊后看哦~????
所屬專欄:C語言學習
貝蒂的主頁:Betty‘s blog
引言
我們在學習C語言的過程中,除了使用最多的頭文件<stdio.h>,還會使用其他頭文件,利用其中的庫函數(shù)幫助我們簡化代碼的過程,比如像<math.h>,<string.h>等頭文件,而今天貝蒂就帶大家詳細了解一下<string.h>吧。
1. 簡介
<string.h>中有很多實用的庫函數(shù),大致分為兩類:一類是像strlen(),strchr()等作用于字符或字符串的字符函數(shù)和字符串函數(shù),今天就讓我們先來介紹字符函數(shù)和字符串函數(shù)吧
2.strlen()函數(shù)
2.1 用法
1.聲明:size_t strlen(const char *str)
- str -- 要計算長度的字符串。
2.作用:計算字符串 str 的長度,直到空結(jié)束字符('\0'),但不包括空結(jié)束字符。
3.返回值:該函數(shù)返回字符串的長度
2.2 實例
strlen()函數(shù)的用法很簡單,貝蒂來簡單介紹一下吧~
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef";
int len = strlen(arr);//計算arr字符串的長度
printf("%d\n", len);
return 0;
}
輸出結(jié)果: 6
2.3 實現(xiàn)strlen()
我們已經(jīng)知道了strlen()函數(shù)的用法,那我們可不可以自我實現(xiàn)一個my_strlen()函數(shù)來模擬strlen()函數(shù)的功能,當然是可以的呀,下面貝蒂將介紹三種實現(xiàn)方法。
(1)計數(shù)法
思路:我們可以用一個指針變量p指向首元素和一個計數(shù)變量count并初始化為0,然后循環(huán)解引用指針所指向的元素,判斷這個元素是否為‘\0’,不是每次p++,count++,是就跳出循環(huán),返回count。
? 代碼實現(xiàn)如下:
#include<stdio.h>
int my_strlen(char* p)
{
int count = 0;
while (*p)//當指向'\0',也就是0,為假跳出循環(huán)
{
p++;//指向下一個元素
count++;//計數(shù)
}
return count;
}
int main()
{
char arr[] = "abcdef";
int len = my_strlen(arr);//計算arr字符串的長度
printf("%d\n", len);
return 0;
}
(2)遞歸法
思路:假設我們要計算字符串“abcdef”的長度,我們可以拆分為1+“bcdef”的長度,同理“bcdef”的長度可以拆分為1+“cdef”的長度......理解了這個思路,我們就可以實現(xiàn)遞歸,首先定義一個指針變量p,如果p!='\0',我們就把p+1作為參數(shù)調(diào)用本函數(shù),直到p為0.
? 代碼實現(xiàn)如下:
int my_strlen(char* p)
{
if (*p != '\0')
{
return 1 + my_strlen(p + 1);//每次調(diào)用p+1指向下一個元素
}
else
{
return 0;//結(jié)束遞歸
}
}
int main()
{
char arr[] = "abcdef";
int len = my_strlen(arr);//計算arr字符串的長度
printf("%d\n", len);
return 0;
(3) 指針-指針
? 首先大家要清楚指針-指針是指在同一空間內(nèi),兩個指針之間的元素個數(shù)。
思路:首先定義兩個指針p1,p2,讓兩個指針指向首元素,然后讓一個指針p2循環(huán)++,直到指向‘\0’就停止,最后返回p2-p1。
? 代碼實現(xiàn)如下:
int my_strlen(char* p1)
{
char* p2 = p1;//使兩個指針都指向首元素
while (*p2)
{
p2++;
}
return p2 - p1;//返回兩指針直接的元素的個數(shù)就是其長度
}
int main()
{
char arr[] = "abcdef";
int len = my_strlen(arr);//計算arr字符串的長度
printf("%d\n", len);
return 0;
}
2.4 sizeof和strlen()的區(qū)別
sizeof() 和 strlen() 的主要區(qū)別在于:
sizeof()
是一個運算符,而strlen()
是一個函數(shù)。sizeof()
計算的是變量或類型所占用的內(nèi)存字節(jié)數(shù),而strlen()
計算的是字符串中字符的個數(shù)。sizeof()
可以用于任何類型的數(shù)據(jù),而strlen()
只能用于以空字符 '\0' 結(jié)尾的字符串。sizeof()
計算字符串的長度,包含末尾的 '\0',strlen() 計算字符串的長度,不包含字符串末尾的 '\0'。
- sizeof和 strlen() 分別是 C 語言中兩個非常常用的關鍵字和函數(shù),它們都與計算內(nèi)存大小有關,但是它們的作用是不同的哦,大家一定要區(qū)分清楚
3. strcmp()函數(shù)
3.1 用法
1.聲明:int strcmp(const char* str1,const char*str2)
- str1 -- 要進行比較的第一個字符串。
- str2 -- 要進行比較的第二個字符串。
2.作用:strcmp() 會根據(jù) ASCII 編碼依次比較 str1 和 str2 的每一個字符,直到出現(xiàn)不到的字符,或者到達字符串末尾(遇見‘
\0’
)3.返回值:
- 如果返回值小于 0,則表示 str1 小于 str2。
- 如果返回值大于 0,則表示 str1 大于 str2。
- 如果返回值等于 0,則表示 str1 等于 str2。
3.2 實例
strcmp用于比較字符串,并返回>0,==0,<0的值,讓我們看看他的具體使用吧
#include<stdio.h>
#include<string.h>
int main()
{
char str1[] = "abcd";
char str2[] = "Abcd";
char str3[] = "abcd";
char str4[] = "bbcd";
int ret1 = strcmp(str1, str2);//比較str1與str2
int ret2 = strcmp(str1, str3);//比較str1與str3
int ret3 = strcmp(str1, str4);//比較str1與str4
printf("%d %d %d\n", ret1, ret2, ret3);
return 0;
}
輸出:1 0 -1
- strcmp()首先會比較第一個字母的ASCII值,如果==則比較第二個字符,直到遇見'\0',若不相等,則返回兩個字符之差”
3.3 實現(xiàn)strcmp()
思路:首先兩個字符串不能改變,且不能傳的參數(shù)不能為空指針,輸入空指針讓編譯器報錯,然后從第一個字符開始比較,直到兩個字符不相等(返回兩個字符之差),如果在不相等之前已經(jīng)指向‘\0’,直接返回0.
代碼實現(xiàn)如下:文章來源:http://www.zghlxwxcb.cn/news/detail-837851.html
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
//經(jīng)const修飾讓*str1與*str2無法改變
{
assert(str1 && str2);//判斷str1和str2是否為空指針
//空指針直接報錯,頭文件<assert.h>
while (*str1== *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char str1[] = "abcd";
char str2[] = "Abcd";
int ret = my_strcmp(str1, str2);
printf("%d\n", ret);
return 0;
}
4. strcpy()函數(shù)
4.1 用法
聲明:char *strcpy(char *dest, const char *src),dest -- 指向用于存儲復制內(nèi)容的目標數(shù)組,src -- 要復制的字符串。
作用:把 src 所指向的字符串復制到 dest。需要注意的是如果目標數(shù)組 dest 不夠大,而源字符串的長度又太長,可能會造成緩沖溢出的情況。
返回值:該函數(shù)返回一個指向最終的目標字符串 dest 的指針。
4.2 實例
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[40];
strcpy(src, "im not betty");
strcpy(dest, src);
printf("最終的目標字符串:%s\n", dest);
return 0;
}
輸出結(jié)果: 最終的目標字符串:im not betty
4.3 實現(xiàn)strcpy()
思路:我們想要將src的內(nèi)容拷貝進des中,首先src的內(nèi)容不能被改變,且保證都不是空指針,然后循環(huán)將src的內(nèi)容賦值給des,直到賦值完‘\0’,條件為假,跳出循環(huán)。
代碼實現(xiàn):
#include<assert.h>
char* my_strcpy(char* des, const char* src)//防止src的內(nèi)容被改變
{
assert(des && src);//防止des與src是空指針
char* ret = des;//作為返回值
while (*des++ = *src++)//循環(huán)拷貝,當拷貝完'\0',判斷為假,跳出循環(huán)
{
;
}
return ret;
}
int main()
{
char src[40] = "abcdef";
char des[40];
my_strcpy(des, src);//將src的內(nèi)容拷貝去des
printf("%s\n", des);
return 0;
}
5.strcat()函數(shù)
5.1用法
- 聲明:char *strcat(char *dest, const char *src)
- dest -- 指向目標數(shù)組,該數(shù)組包含了一個 C 字符串,且足夠容納追加后的字符串。
- src -- 指向要追加的字符串,該字符串不會覆蓋目標字符串。
作用:把 src 所指向的字符串追加到 dest 所指向的字符串的結(jié)尾。
返回值:該函數(shù)返回一個指向最終的目標字符串 dest 的指針。
5.2實例
#include <stdio.h>
#include <string.h>
int main()
{
char src[50];
char dest[50];
strcpy(src, "world!");
strcpy(dest, "hello ");
strcat(dest, src);
printf("最終的目標字符串:%s", dest);
return 0;
}
輸出結(jié)果:最終的目標字符串:hello world!
- 因為strcat()函數(shù)的實現(xiàn)機制,所以strcat()無法對自己追加(會出現(xiàn)死循環(huán)),如果要實現(xiàn)自己對自己的追加可以使用strncat()函數(shù),這個后面貝蒂會為大家講解
5.3 實現(xiàn)strcat()
思路:實現(xiàn)strcat的方法其實和實現(xiàn)strcpy的方法類似,都是替換,只是要讓dest先指向末尾'\0'。
代碼實現(xiàn):
char* my_strcat(char* dest, const char* src)//防止src的值被改變
{
assert(dest && src);//不能為空指針
char* ret = dest;
while (*dest)//使dest指向末尾
{
dest++;
}
while (*dest++ = *src++)//循環(huán)賦值
{
;
}
return ret;
}
int main()
{
char dest[20] = "hello ";
char src[20] = "world!";
my_strcat(dest, src);
printf("%s", dest);
return 0;
}
6. strchr()函數(shù)
6.1用法
- 聲明:char *strchr(const char *str, int c)
- str -- 要查找的字符串。
- c -- 要查找的字符。
作用:在參數(shù) str 所指向的字符串中搜索第一次出現(xiàn)字符 c(一個無符號字符)的位置。
返回值:如果在字符串 str 中找到字符 c,則函數(shù)返回指向該字符的指針,如果未找到該字符則返回 NULL。
6.2實例
#include<string.h>
int main()
{
char arr[20] = "hello betty";
char* p = strchr(arr,'y');
if (*p == NULL)
{
printf("沒找到\n");
}
else
{
printf("找到了\n");
}
return 0;
}
6.3 實現(xiàn)strchr()
思路:一樣先排查空指針,然后循環(huán)尋找,如果尋找到,直接返回其地址。找不到就返回空指針NULL
代碼實現(xiàn):
char* my_strchr(const char* str, int c)
{
assert(str);//排查空指針
while (*str)
{
if (*str == c)
{
return str;//找到返回其地址
}
str++;
}
return NULL;//找不到返回空指針
}
int main()
{
char arr[20] = "hello betty";
char* p =my_strchr(arr,'y');
if (*p == NULL)
{
printf("沒找到\n");
}
else
{
printf("找到了\n");
}
return 0;
}
7. strstr()函數(shù)
7.1 用法
- 聲明:char *strstr(const char *haystack, const char *needle)
haystack -- 要被檢索的 C 字符串。
needle -- 在 haystack 字符串內(nèi)要搜索的小字符串。
作用:在字符串 haystack 中查找第一次出現(xiàn)字符串 needle 的位置,不包含終止符 '\0'。
返回值:該函數(shù)返回在 haystack 中第一次出現(xiàn) needle 字符串的位置,如果未找到則返回 空指針(NULL)
7.2實例
#include <stdio.h>
#include <string.h>
int main()
{
char haystack[20] = "hello betty";
char needle[10] = "betty";
char* ret = strstr(haystack, needle);
if (ret == NULL)
{
printf("未找到\n");
}
else
{
printf("找到啦,子字符串是:%s\n", ret);
}
return 0;
}
輸出結(jié)果:找到啦,子字符串是:betty
7.3 實現(xiàn)strstr()
思路:首先用是用s1,s2指向兩個字符串的首元素,用p記錄str1中開始比較的元素的位置,方便重新開始比較。然后循環(huán)比較,如果*s1!=*s2,或者遇見‘\0’,就跳出循環(huán),判斷,如果是s2為‘\0’,說明配對成功,s1為‘\0’,則說明后續(xù)長度不夠,匹配失敗啦,除開以上情況,就讓p++,重復上述流程,直到*p==‘\0’
情況1:在acbcef中查找acb
代碼實現(xiàn)如下:
#include <stdio.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);//防止空指針
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;//記錄初始位置
while (*p)
{
s1 = p;//從記錄位置開始比較
s2 =str2;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')//配對成功
{
return (char*)p;//p原本被const修飾
}
else if (*s1 == '\0' && s2 != '\0')//s1后續(xù)字符少于s2
{
return NULL;
}
p++;//記錄下一個位置
}
return NULL;
}
int main()
{
char haystack[20] = "hello betty";
char needle[10] = "betty";
char* ret =my_strstr(haystack, needle);
if (ret == NULL)
{
printf("未找到\n");
}
else
{
printf("找到啦,子字符串是:%s\n", ret);
}
return 0;
}
本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!文章來源地址http://www.zghlxwxcb.cn/news/detail-837851.html
到了這里,關于掌握字符與字符串:C語言中的神奇函數(shù)解析(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!