免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

字符串+內存函數(C語言)-創新互聯

目錄

10年專注成都網站制作,成都企業網站建設,個人網站制作服務,為大家分享網站制作知識、方案,網站設計流程、步驟,成功服務上千家企業。為您提供網站建設,網站制作,網頁設計及定制高端網站建設服務,專注于成都企業網站建設,高端網頁制作,對成都會所設計等多個領域,擁有多年建站經驗。

函數介紹:

字符串函數:

strlen

一道迷惑筆試題:

strcpy

strcat

strcmp

strncpy

strncat

strncmp

strstr

strtok

strerror

字符分類函數:

iscntrl?

isspace

isdigit

isxdigit

islower

isupper

isalpha

isalnum

ispunct

isgraph

isprint

tolower

toupper

內存函數:

memcpy

memmove

memcmp

memset

庫函數的模擬實現

模擬實現strlen

模擬實現strcpy

模擬實現strcat

模擬實現strstr

模擬實現strcmp

模擬實現memcpy

模擬實現memmove


對C語言中的幾個常用的庫函數進行解釋說明

并徹底了解如何使用

了解原理,并進行模擬實現

函數介紹: 字符串函數:
strlen

計算字符串長度函數

函數原型:size_t? strlen(const char* str)

返回值:size_t? ?就是??unsigned int 無符號整型

?返回的是'\0‘之前字符的個數?

參數:const char* str??

?是一個char*的指針 且用const修飾

?const修飾的是*str

表示指針指向的內容是不可被修改的

函數作用:計算的是字符串長度

計算'\0'之前字符的個數

函數的用途:看以下代碼:

#include#includeint main()
{
	//創建一個數組 用來封裝字符串
	char str[] = "abcdefghjk";
	
	//調用strlen函數,用一個size_t 無符號整型來接收
	//將str數組名表示首元素地址,也就是字符串的首地址傳過去
	size_t len = strlen(str);

	//打印,從傳過去的位置開始,遇到'\0'之前,字符的個數
	printf("%u\n", len);

	return 0;
}
一道迷惑筆試題:
#include#includeint main()
{
	const char* str1 = "abcdef";
	const char* str2 = "bbb";

	if (strlen(str2) - strlen(str1) >0)
	{
		printf("str2>str1\n");
	}
	else
	{
		printf("srt1>str2\n");
	}

//在判斷的時候,strlen(str2)的值為3
//strlen(str1)的值為6
//而 3 和 6 都是size_t類型
//3-6 的實際結果為:-3
// -3 :
// 原碼:10000000 00000000 00000000 00000011
// 反碼:11111111 11111111 11111111 11111100
// 補碼:11111111 11111111 11111111 11111101
// 
//但因為是無符號整型,將-3的補碼實際解讀的時候
//是按照無符號數來解讀的,因為正數的 原碼,反碼,補碼相同
//所以將-3的補碼當做原碼解讀,是一個很大的數
//該數必定大于0 所以必定指向if里面的語句

	return 0;
}

解析:

答案:str2>str1

在判斷的時候,strlen(str2)的值為3
strlen(str1)的值為6
而 3 和 6 都是size_t類型
3-6 的實際結果為:-3
-3 :
原碼:10000000 00000000 00000000 00000011
反碼:11111111 11111111 11111111 11111100
補碼:11111111 11111111 11111111 11111101

但因為是無符號整型,將-3的補碼實際解讀的時候
是按照無符號數來解讀的,因為正數的 原碼,反碼,補碼相同
所以將-3的補碼當做原碼解讀,是一個很大的數
該數必定大于0 所以必定指向if里面的語句

strcpy

字符串拷貝函數

函數原型:char * strcpy ( char * destination, const char * source );

參數:char * destination, const char * source

將source指向的字符串復制到destination指向的數組中

包括終止字符'\0’也要賦值過去

返回值:char*??

返回的是sourec指向的那一片空間的地址

函數作用:將源頭src指向字符串的內容賦值到目的地dest指向字符串中

?在賦值的時候會將字符'\0’也賦值過去

???????為避免溢出,destination指向的數組的大小應足夠長

以包含與source相同的字符串(包括終止空字符),

并且不應與source在內存中重疊。

函數的使用:看以下代碼:

#include#includeint main()
{
	//將str2的內容拷貝到str1中
   //拷貝的時候會將'\0'也拷貝過去
  //str1的空間要足夠大要裝的下str2的內容!
	char str1[20] = "zzzzzzzzzzzzzz";
	char str2[] = "abcde";
	strcpy(str1, str2);
	printf("%s\n", str1);

	//將s2的內容拷貝到s1中
	//拷貝的時候會將'\0'也拷貝過去
	//s1的空間要足夠大要裝的大s2的內容
	char s1[] = "xxxxxxxxxx";
	char s2[] = "fghijk";
	strcpy(s1, s2);
	printf("%s\n", s1);

	//將p2指向的常量字符串的內容拷貝到p2中
	//拷貝的時候會將'\0'也拷貝過去
	//p1的空間要足夠大要裝的大p2的內容
	char p1[20] = "yyyyyyyyyyyyyyyyyy";
	char* p2 = "lmnopq";
	strcpy(p1, p2);
	printf("%s\n", p1);

	return 0;
}
strcat

字符串追加函數

函數原型:char * strcat ( char * destination, const char * source );

返回值:char*

返回的是追加完成之后

destination的首地址

參數:char * destination, const char * source

?destination是目的地字符串的首地址

?source 是源頭字符串的首地址

函數作用:

將source指向的字符串內容

追加到destination指向的字符串后面

追加時:destination中的'\0'被source的第一個字符覆蓋

destination指向的空間要足夠大

要容納下追加之后的新字符串

函數用途:看以下代碼? ? ? ?

#include#includeint main()
{
	//將str2的內容追加到str1的后面
	//在追加的時候str1最后的‘\0’字符被str2的第一個字符覆蓋
	//然后進行追加,追加時會將str2的'\0'也追加進去
	//str1的空間要足夠大,要能容納下追加后的新字符串
	char str1[50] = "abcdefg";
	char str2[] = "hijklmn";
	strcat(str1, str2);
	printf("%s\n", str1);

	//將p2指向的常量字符串內容追加到p1的后面
	//追加時p1的'\0'字符被p2的首字符覆蓋
	//追加時會將p2的'\0'也追加進去
	//p1的空間要足夠大,能容納下追加后的新字符串
	char p1[20] = "abc";
	char* p2 = "defgk";
	strcat(p1, p2);
	printf("%s\n", p1);

	return 0;
}

?

strcmp

字符串比較函數

函數原型:int strcmp ( const char * str1, const char * str2 );

返回值:int

???返回的是一個有符號整型數

?可返回負數,0,正數

參數:const char * str1, const char * str2

?str1指向一個字符串,

?str1里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

?str2也指向一個字符串,

?str2里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

?

函數的作用:

?????str1字符串與str2字符串從首字符的位置開始

?????一個字符一個字符對應向后一一比較,

?????在比較字符的時候比較的是其ASCII碼值,

?????若對應比較兩個字符相等則一直向后比較,

?????直到碰到字符不等的情況就停止比較,

?????然后返回這兩個不等字符的比較結果,

?????當str1的字符大于str2的字符 則返回大于0的數字,

?????若兩個字符串比較完了,各字符都相同,

?????且長度相等的情況下,則這兩個字符串相等

?????str1等于str2時返回0,

?????str1的字符小于str2的字符時 返回小于0的數

函數用途:如下代碼:

#include#includeint main()
{
	//字符串比較
	//str1 與 str2 進行比較
	//從首字符開始向后一一比較
	//在比較的時候比較的是字符的ASCII碼值
	//若對應的字符相等,則繼續向后比較
	//若不等,則停止比較,返回他們的比較結果
	//若兩個字符串比較完都相等,且長度一樣長,說明str2和str2相等
	//返回值:
	//第一個字符串大于第二個字符串,則返回大于0的數字
	//第一個字符串等于第二個字符串,則返回0
	//第一個字符串小于第二個字符串,則返回小于0的數字

	char str1[] = "abcde";
	char str2[] = "abcfk";
	int n = strcmp(str1, str2);
	if (n == 0)
	{
		printf("str1 == str2");
	}
	else if (n >0)
	{
		printf("str1 >str2");
	}
	else
	{
		printf("str1< str2");
	}

	return 0;
}

strncpy

字符串拷貝函數(指定字節數拷貝)

函數原型:char * strncpy ( char * destination, const char * source, size_t num );

返回值:char *

?返回的是一個char* 的指針

?返回的是拷貝完成后的destination指向的空間

參數:char * destination, const char * source, size_t num

?目的地字符串:

?destination 是指向一個字符串空間的指針

?源頭字符串:

?soure是一個指向一個字符串空間的指針

?const修飾說明soure指向的字符串不可被修改

?num是一個sizt_t 無符號整型的數字

函數的作用:

?????將soure指向的字符串中num個字節的內容

?????復制到destination指向的字符串空間

?????如果source指向的字符串的長度小于num,

?????則拷貝完源字符串之后,在目標的后邊追加0,

?????直到追加夠num個結束

?????destination 指向的空間要足夠大

?????至少能容納下拷貝后新的字符串

函數用途:如下代碼:

#include#includeint main()
{
	//拷貝num個字符從源字符串到目標空間。
	//如果源字符串的長度小于num,則拷貝完源字符串之后,
	//在目標的后邊追加0,直到num個

	char str1[] = "yyyyyyyyyyyyyyyyyyy";
	char str2[] = "hello";
	strncpy(str1, str2, 5);
	printf("%s\n", str1);

	//當s2的長度

strncat

字符串追加函數(指定字節數追加)

函數原型:char * strncat?( char * destination, const char * source, size_t num );

返回值:char *

??返回的是一個char*的指針

返回追加完成之后destination指向的空間

參數:char * destination, const char * source, size_t num

?目的地字符串:

?destination 是指向一個字符串空間的指針

?源頭字符串:

?soure是一個指向一個字符串空間的指指針

?const修飾 說明soure指向的字符串不可被修改

?num是一個sizt_t 無符號整型的數字

函數的作用:

?????將soure指向的字符串中num個字節的內容

? 追加到destination指向的字符串空間

?????destination指向字符串的最后的'\0'字符

?????會被soure指向的字符串的首字符所覆蓋

?????如果source指向的字符串的長度大于num,

?????則追加完num個字符之后,在后邊自動加上'\0'

?????如果source指向的字符串的長度小于num,

? 則只追加完source指向的字符串內容(包含'\0’)

?????就結束結束追加

?????destination 指向的空間要足夠大

?????至少能容納下追加后新的字符串

函數用途:如下代碼:

#include#includeint main()
{
	//str2 大于 num 的情況
   //會自動在末尾加上'\0'
	//在追加的時候,str1的'\0'會被str2的首字符所覆蓋
	char str1[50] = "uvwxy";
	char str2[] = "abcdefg";
	strncat(str1, str2, 5);
	printf("%s\n", str1);

	//str2 小于 num 的情況
	//只追加完str2包含'\0’字符就結束追加
	//在追加的時候,s1的'\0'會被s2的首字符所覆蓋
	char s1[50] = "wasche";
	char s2[] = "hello world";
	strncat(s1, s2, 13);
	printf("%s\n", s1);

	return 0;
}

strncmp

字符串比較函數(指定字節數比較)

函數原型:int strncmp ( const char * str1, const char * str2, size_t num );

返回值:int

???返回的是一個有符號整型數

?可返回負數,0,正數

參數:const char * str1, const char * str2, size_t num

?str1指向一個字符串,

?str1里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

?str2也指向一個字符串,

?str2里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

?num是一個無符號整數,表示字節數

函數的作用:

? 對str1和str2字符串,指定num個字節進行比較

?????str1字符串與str2字符串從首字符的位置開始

? 比較到num個字節結束

?????一個字符一個字符對應向后一一比較,

?????在比較字符的時候比較的是其ASCII碼值,

?????若對應比較兩個字符相等則一直向后比較,

?????直到碰到字符不等的情況就停止比較,

?????然后返回這兩個不等字符的比較結果,

?????當str1的字符大于str2的字符 則返回大于0的數字,

?????若兩個字符串比較num個字節之后,

?????各字符都相同,則這兩個字符串相等

?????str1等于str2時返回0,

?????str1的字符小于str2的字符時 返回小于0的數

?????若字符串的長度小于num,則比較完字符'\0'就結束比較

函數用途:如下代碼:

#include#includeint main()
{
	char str1[] = "abcdefghijklm";
	char str2[] = "abcdefgxyz";
	//比較前六個字符是否相等
	int n = strncmp(str1, str2, 6);
	if (n == 0)
	{
		printf("str1 == str2\n");
	}
	else if (n >0)
	{
		printf("str1 >str2\n");
	}
	else
	{
		printf("str1< str2\n");
	}


	//比較前8個字符是否相等
	n = strncmp(str1, str2, 8);
	if (n == 0)
	{
		printf("str1 == str2\n");
	}
	else if (n >0)
	{
		printf("str1 >str2\n");
	}
	else
	{
		printf("str1< str2\n");
	}

	//比較前11個字符是否相等
	n = strncmp(str1, str2, 11);
	if (n == 0)
	{
		printf("str1 == str2\n");
	}
	else if (n >0)
	{
		printf("str1 >str2\n");
	}
	else
	{
		printf("str1< str2\n");
	}

	return 0;
}

strstr

字符串找子串函數

函數原型:char * strstr ( const char *str1, const char * str2);

返回值:char *

返回一個字符指針

?返回找到子串的首字符的地址

找不到返回NULL

參數:const char *str1, const char * str2

?str1指向一個字符串,

?str1里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

?str2也指向一個字符串,

?str2里面存放的是字符串的首地址

?用const修飾說明字符串的內容不可被修改

函數的作用:

? 尋找在str1指向的常量字符串里

?????是否包含str2指向的字符串

?????若包含則返回str2第一次出現的地址

?????若不包含則返回NULL

函數用途:如下代碼:

#include#includeint main()
{
	//查找str2是否是str1的子串
	//若是則返回str2第一次出現的位置
	//若不是則返回NULL
	char str1[] = "abcdefgjklcdefgmn";
	char str2[] = "cdef";
	char* p = strstr(str1, str2);
	if (p == NULL)
	{
		printf("str2 不是 str1 的子串\n");
	}
	else
	{
		printf("str2 是 str1 的子串\n");
		//用%s打印的時候會從str2在str1中第一次出現的位置開始,直到遇到'\0'結束
		printf("%s\n", p);
	}

	return 0;
}

strtok

字符串分割函數

函數原型:char * strtok ( char * str, const char * sep );

返回值:char *

??返回一個字符指針

??返回用分割符號分割后字符串的首地址

參數:char * str, const char * sep

str是一個指向要被分割的字符串的空間

sep指向的是分割符號的字符串空間

用const修飾說明sep指向的內容不可被修改

函數的作用:

sep里面傳過來的是分隔符的字符串

在第一次調用的時候

str里面傳過來的是要被分割字符串的首地址

在查找分隔符的時候會將分隔符的位置改為'\0'

在第二次調用的時候

str里面傳入一個空指針,

此時查找分隔符的位置會在第一次分隔符的下一個字符開始查找

會找到下一個分隔符,再將分隔符的位置改為'\0‘

以此類推有幾個分隔符就查找幾次

sep參數是個字符串,定義了用作分隔符的字符集合
第一個參數指定一個字符串,

它包含了0個或者多個由sep字符串中一個或者多個分隔符分割的標記。
strtok函數找到str中的下一個標記,

并將其用 \0 結尾,

返回一個指向這個標記的指針。

(注:
??? strtok函數會改變被操作的字符串,

????????? ?所以在使用strtok函數切分的字符串

????????一般都是臨時拷貝的內容并且可修改。)
strtok函數的第一個參數不為 NULL ,

函數將找到str中第一個標記,

strtok函數將保存它在字符串中的位置。
strtok函數的第一個參數為 NULL ,

函數將在同一個字符串中被保存的位置開始,

查找下一個標記。
如果字符串中不存在更多的標記,則返回 NULL 指針

函數用途:如下代碼:

#include#includeint main()
{
	char str[] = "hello@world&string#strtok";//被分割的字符串
	char ep[] = "@&#";//分隔符字符串

	//第一次調用 會將找到的分割符的位置改為'\0'
	char* p = strtok(str, ep);
	printf("%s\n", p);

	//第二次調用傳入空指針 會將找到的分割符的位置改為'\0'
	p = strtok(NULL, ep);
	printf("%s\n", p);

	//第三次調用也傳入空指針 會將找到的分割符的位置改為'\0'
	p = strtok(NULL, ep);
	printf("%s\n", p);

	//第四次調用也傳入NULL 會將找到的分割符的位置改為'\0'
	p = strtok(NULL, ep);
	printf("%s\n", p);


	上述我們打印分割的字符串總共調用了四次
	代碼寫的有點繁瑣,我們可以用一個for循環直接調用打印
	//char* ret = NULL;
	//for (ret = strtok(str, ep);ret!=NULL; ret = strtok(NULL, ep))
	//{
	//	printf("%s\n", ret);
	//}

	return 0;
}

strerror

獲取錯誤信息函數

函數原型:char * strerror ( int errnum );

返回值:char *

? 返回一個字符指針

??返回的是錯誤信息是字符串

參數:int errnum

參數是一個整數

傳入的是一個錯誤碼

函數的作用:

? 返回一個字符串,而這個字符串

? 就是一串錯誤信息

? 而參數是一個整數,是一個錯誤碼

? 每一個錯誤碼都有一個對應的錯誤信息

函數用途:如下代碼:

#include#include#includeint main()
{
	//隨便傳入一個錯誤碼,打印出其錯誤信息
	printf("%s\n", strerror(12));

	//具體應用
	//FILE是一個文件指針,fopen是打開文件
	//在當前目錄下打開text.txt文件進行讀操作
	//若打開失敗返回NULL
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		printf("打開失敗錯誤信息為:%s",strerror(errno));
	}
	else
	{
		printf("打開成功\n");
	}

	return 0;
}

字符分類函數:

頭文件包含:#include

iscntrl?

字符控制函數

函數原型:int iscntrl ( int c );

函數的作用:

? 傳入一個字符,

判斷是否是控制字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = iscntrl(c);
	if (ret == 0)
	{
		printf("%c不是控制字符\n", c);
	}
	else
	{
		printf("%c 是控制字符\n", c);
	}

	return 0;
}
isspace

空白字符:‘空格’,‘\f’換頁,'\n'換行,

?????'\r'回車,制表符‘\t’,垂直制表符'\v'

函數原型:int isspace ( int c );

函數作用:

? 傳入一個字符,

判斷是否是空白字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	//空白字符:‘空格’,‘\f’換頁,'\n'換行,'\r'回車,制表符‘\t’,垂直制表符'\v'
	char c = '\n';
	int ret = iscntrl(c);
	if (ret == 0)
	{
		printf("%c不是空白字符\n", c);
	}
	else
	{
		printf("%c 是空白字符\n", c);
	}

	return 0;
}
isdigit

十進制數字0~9

函數原型:int isdigit ( int c );

函數作用:

? 傳入一個字符,

判斷是否是0~9的字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isdigit(c);
	if (ret == 0)
	{
		printf("%c不是0~9字符\n", c);
	}
	else
	{
		printf("%c 是0~9字符\n", c);
	}

	return 0;
}
isxdigit
十六進制數字,包括所有十進制數字,小寫字母a~f,大寫字母A~F

函數原型:int isdigit ( int c );

函數作用:

? 傳入一個字符,

判斷是否是十六進制數

小寫字母a~f,大寫字母A~F的字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isxdigit(c);
	if (ret == 0)
	{
		printf("%c NO is 十六進制\n", c);
	}
	else
	{
		printf("%c YES 十六進制\n", c);
	}

	return 0;
}
islower

小寫字母:a~z

函數原型:int islower?( int c );

函數作用:

? 傳入一個字符,

判斷是否是小寫字母:a~z

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = islower(c);
	if (ret == 0)
	{
		printf("%c NO is 小寫字母\n", c);
	}
	else
	{
		printf("%c YES 小寫字母\n", c);
	}

	return 0;
}
isupper

大寫字母A~Z

函數原型:int isupper?( int c );

函數作用:

? 傳入一個字符,

判斷是否是大寫字母:A~Z

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isupper(c);
	if (ret == 0)
	{
		printf("%c NO is 大寫字母\n", c);
	}
	else
	{
		printf("%c YES 大寫字母\n", c);
	}

	return 0;
}
isalpha

字母a~z或者A~Z

函數原型:int isalpha?( int c );

函數作用:

? 傳入一個字符,

判斷是否是大寫或者小寫字母

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isalpha(c);
	if (ret == 0)
	{
		printf("%c NO is 字母\n", c);
	}
	else
	{
		printf("%c YES 字母\n", c);
	}

	return 0;
}
isalnum

字母或者數字,A~Z ,a~z,0~9

函數原型:int isalnum?( int c );

函數作用:

? 傳入一個字符,

判斷是否是

大寫或者小寫字母或者是數字字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isalnum(c);
	if (ret == 0)
	{
		printf("%c NO is 字母或數字\n", c);
	}
	else
	{
		printf("%c YES 字母或數字\n", c);
	}

	return 0;
}
ispunct

標點符號,任何不屬于數字或者字母的圖形字符(可打印)

函數原型:int ispunct?( int c );

函數作用:

? 傳入一個字符,

判斷是否是

? 不屬于數字或者字母的圖形字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = ispunct(c);
	if (ret == 0)
	{
		printf("%c NO is 它屬于數字或字母\n", c);
	}
	else
	{
		printf("%c YES  它不屬于字母或數字\n", c);
	}

	return 0;
}
isgraph

任何圖形字符

函數原型:int isgraph?( int c );

函數作用:

? 傳入一個字符,

判斷是否是圖形字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isgraph(c);
	if (ret == 0)
	{
		printf("%c NO is 它不是圖形字符\n", c);
	}
	else
	{
		printf("%c YES  它是圖形字符\n", c);
	}

	return 0;
}
isprint

任何可打印字符,包括圖形字符和空白字符

函數原型:int isprint?( int c );

函數作用:

? 傳入一個字符,

判斷是否是可打印的字符

? 包含圖形字符和空白字符

若是則返回非0數(也就是ture)

若不是則返回0(也就是false)

函數用途:

#include#includeint main()
{
	char c = 0;
	scanf("%c", &c);
	int ret = isprint(c);
	if (ret == 0)
	{
		printf("%c NO is 它不是可打印的字符\n", c);
	}
	else
	{
		printf("%c YES  它是可打印的字符\n", c);
	}

	return 0;
}
tolower

字母大寫轉小寫

函數原型:int tolower?( int c );

函數作用:

? 傳入一個字符,

判斷是否是大寫字母A~Z

? 若是將其轉為對應小寫字母

函數用途:

#include#include#includeint main()
{
	//將字符串的大寫字母全部轉為小寫字母
	char str[] = "abcDEfGjK";
	int i = 0;
	for (i = 0; i< strlen(str); i++)
	{
		if (isupper(str[i])!=0)//判斷是否是大寫字母
		{
			str[i] = tolower(str[i]);//大寫轉小寫
		}
	}
	printf("%s\n", str);

	return 0;
}
toupper

字母小寫轉大寫

函數原型:int toupper?( int c );

函數作用:

? 傳入一個字符,

判斷是否是小寫字母a~z

? 若是將其轉為對應大寫字母

函數用途:

#include#include#includeint main()
{
	//將字符串的小寫字母全部轉為大寫字母
	char str[] = "abcDEfGjK";
	int i = 0;
	for (i = 0; i< strlen(str); i++)
	{
		if (islower(str[i])!=0)//判斷是否是小寫字母
		{
			str[i] = toupper(str[i]);//小寫轉大寫
		}
	}
	printf("%s\n", str);

	return 0;
}

內存函數:
memcpy

內存拷貝函數

函數原型:void * memcpy ( void * destination, const void * source, size_t num );

返回值:void?*

? 返回值是一個任意類型的指針

?返回拷貝好的內存空間的起始地址

參數:void * destination, const void * source, size_t num

目的地:

destination是一個任意類型的指針

源頭:

source是一個任意類型的指針

? 用const修飾,

說明source指向的內存空間的內容不可修改

字節數:

num是一個無符號整型

函數的作用:

將source 指向的空間

里面的num個字節的數據

復制到destination指向的空間中

返回值,返回的是:

拷貝好之后 destination指向的空間的地址

? destination指向的內存空間要足夠大

? 至少能容納下拷貝之后的數據

? 這個函數遇到'\0'時根本就不會停下來

? 直到拷貝夠num字節數就停止

? memcpy函數不能勝任重疊拷貝

? 自己拷貝自己

函數用途:如下代碼:

#include#include// 定義結構體
struct {
	char name[40];
	int age;
} person, person_copy;
//創建結構體全局變量 person,和 per_copy

int main()
{
	char myname[] = "Pierre de Fermat";
	//創建一個字符串
	
	//將myname整個字符串的內容,拷貝到結構體變量person 的成員變量 name 空間中
	memcpy(person.name, myname, strlen(myname) + 1);
	//再給變量person的成員變量 age 賦值為46
	person.age = 46;

	//將變量person 的空間的內容,全部拷貝 到變量 person_copy的空間中
	memcpy(&person_copy, &person, sizeof(person));
	//將變量 person_copy 空間中的內容打印出來 
	printf("person_copy: %s, %d \n", person_copy.name, person_copy.age);

	return 0;
}

memmove

內存拷貝函數(指定字節數)

函數原型:void * memmove ( void * destination, const void * source, size_t num );

返回值:void?*

? 返回值是一個任意類型的指針

?返回拷貝好的內存空間的起始地址

參數:void * destination, const void * source, size_t num

目的地:

destination是一個任意類型的指針

源頭:

source是一個任意類型的指針

? 用const修飾,

說明source指向的內存空間的內容不可修改

字節數:

num是一個無符號整型

函數的作用:

將source 指向的空間

里面的num個字節的數據

復制到destination指向的空間中

返回值,返回的是:

拷貝好之后 destination指向的空間的地址

? destination指向的內存空間要足夠大

? 至少能容納下拷貝之后的數據

? 這個函數遇到'\0'時根本就不會停下來

? 直到拷貝夠num字節數就停止

? memmove函數可以勝任重疊拷貝

? 自己可以拷貝自己

函數用途:如下代碼:

#include#includeint main()
{
	//創建字符串數組并初始化
	char str[] = "memmove can be very useful......";

	//str+20 取到的是字符u的地址
	//str+15 取到的是字符v的地址
	//從v字符還是往后拷貝11個字節的數據到 str+20的位置
	//自己拷貝自己 重疊拷貝
	memmove(str + 20, str + 15, 11);

	//打印重疊拷貝后的str
	puts(str);

	return 0;
}

memcmp

內存比較函數

函數原型:int memcmp ( const void * ptr1,const void * ptr2,size_t num );

返回值:int

返回一個有符號整數

返回小于0的數

返回等于0的數

返回大于0的數

參數:const void * ptr1,const void * ptr2,size_t num

目的地:

ptr1指向任意類型的一塊內存空間

用const修飾

說明ptr1指向的空間的內容不可被修改

源頭:

ptr2指向任意類型的一塊內存空間

用const修飾

說明ptr2指向的空間的內容不可被修改

num是一個無符號整型

表示字節個數

函數作用:

從ptr1和ptr2分別指向空間首地址開始

一個字節一個字節,一一對應進行比較

比較num個字節,

當ptr1大于ptr2返回大于0的數

當ptr1等于ptr2返回數字0

當ptr1小于ptr2返回小于0的數

函數用途:如下代碼:

#include#includeint main()
{
	//創建兩個字符串
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";

	//將buffer1 跟 buffer2 的 前sizeof(buffer1) 個字節 進行比較
	//一個字節 一個字節 往后一一比較 要是相同往后繼續比較
	//只要遇到不等的字節 就停止比較,返回這兩個字節比較的結果
	//buffer1 大于 buffer2 返回大于0的數字
	//buffer1 等于 buffer2 返回數字0
	//buffer1 小于 buffer2 返回小于0的數
	int n = 0;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));

	if (n >0) 
		printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n< 0) 
		printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else
		printf("'%s' is the same as '%s'.\n", buffer1, buffer2);

	return 0;
}

memset

內存填充函數

函數原型:void * memset ( void * ptr, int value, size_t num );

返回值:void *

?返回任意類型的指針

?返回被修改后的內存空間的地址

參數:void * ptr, int value, size_t num

ptr是一個任意類型的指針

指向一片任意類型的空間

value是一個有符號整型

表示要修改的值

num是一個無符號整型

表示要修改的字節數

函數作用:

將ptr指向的內存塊

? 前num個字節的內容設置為value

? 從ptr的位置開始向后num個字節

? 的內容修改成value

函數用途:如下代碼

#include#includeint main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//數組名表示數組首元素地址
	//將arr指向的內存塊的前20個字節,每個字節的內容都設置為0
	memset(arr, 0, 20);
	int i = 0;
	for (i = 0; i< sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	char str[] = "xxxxxxxxx";
	//將str指向的內存塊的前5個字節,每個字節的內容都設置為'a’
	memset(str, 'a', 5);
	printf("%s\n", str);

	return 0;
}

庫函數的模擬實現
模擬實現strlen

函數原型:size_t strlen(const char* str);

原理:strlen函數是計算字符串的長度

?也就是計算'\0'之前的字符的個數

模擬實現:

實現1:

#includesize_t my_strlen(const char* str)
{
	size_t count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char str[] = "abcdefgh";
	size_t len = my_strlen(str);
	printf("%d\n", len);

	return 0;
}

實現2:

#include//遞歸方式實現
size_t my_strlen(const char* str)
{
	if (*str != '\0')
	{
		return 1 + my_strlen(str+1);
	}
	return 0;
}

int main()
{
	char str[] = "abcdefgh";
	size_t len = my_strlen(str);
	printf("%d\n", len);

	return 0;
}

實現3:

#includesize_t my_strlen(const char* str)
{
	char* p = str;
	while (*str++);
	return str - p - 1;
}
int main()
{
	char str[] = "abcdefgh";
	size_t len = my_strlen(str);
	printf("%d\n", len);

	return 0;
}

模擬實現strcpy

函數原型:char * strcpy ( char * destination, const char * source );

原理:strcpy就是將source指向空間的內容

?復制到destination指向的空間里

?在復制的同時會將source的'\0'也復制過去

?復制完成后將str1返回

模擬實現:

#include#include 

//模擬實現strcpy
char* my_strcpy(char* str1, const char* str2)
{
	assert(str1 && str2);
	char* p = str1;
	while (*str1++ = *str2++);

	return p;
}

int main()
{
	char str1[50] = "xxxxxxxxxxxxxxxxxxxx";
	char str2[] = "abcdefg";
	
	//將str2的內容賦值到str1中
	//str1的空間要足夠大
	my_strcpy(str1, str2);
	printf("%s\n", str1);

	return 0;
}

模擬實現strcat

函數原型:char * strcat ( char * destination, const char * source );

原理:將source指向的字符串的內容

?追加到destination指向的字符串的后面

?追加的時候destination字符串的'\0'字符

?會被source字符串的首字符覆蓋

?且會將source字符串的'\0'也追加上來

?且返回追加完成后的destination

模擬實現;

#include#include 

//模擬實現 strcat
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* p = dest;
	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++));

	return p;
}

int main()
{
	char str1[50] = "abcdef";
	char str2[] = "ghijklmn";

	//將str2字符串的內容追加到str1后面
	//在追加的時候會將str1字符串的'\0'覆蓋掉
	my_strcat(str1, str2);
	printf("%s\n", str1);

	return 0;
}

模擬實現strstr

函數原型:const char * strstr ( const char * str1, const char * str2 );

原理:尋找str1這個字符串中是否包含str2字符串

若是包含則返回str2第一次出現的位置

否則返回NULL

也就是判斷str2是否是str1的子串

模擬實現:

#include#include 

//模擬實現strstr函數
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* p = (char*)str1;
	char* s1 = NULL;
	char* s2 = NULL;
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	while (*p)
	{
		s1 = p;
		s2 = (char*)str2;
		while (*s1 && *s2 && !(*s1 - *s2))
		{
			s1++;
			s2++;
		}
		if (!*s2)
		{
			return p;
		}
		p++;
	}
	return NULL;
}

int main()
{
	char str1[] = "kkkabcdefghijklmnabcdefgxyz";
	char str2[] = "abcdef";

	//查找str2是否是str1的子串
	//若是返回str2第一次出現的位置
	//不是則返回NULL
	char* p = my_strstr(str1, str2);
	if (p == NULL)
	{
		printf("不是子串\n");
	}
	else
	{
		printf("是子串\n");
		printf("從返回的地址處開始打?。?s\n", p);
	}

	return 0;
}

模擬實現strcmp

函數原型:int strcmp ( const char * str1, const char * str2 );

原理: 讓str1字符串與str2字符串

?從首字符開始一個字符一個字符向后比較

?若兩個字符相等則繼續向后比較

?直到出現兩個字符不等的情況下停止比較

?并且返回這兩個不同字符比較的結果

?若str1大于str2返回大于0的數

?若str1等于str2返回等于0的數

?若str1小于str2返回小于0的數

模擬實現:

#include#include 

//模擬實現strcmp函數
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);

	while (*str1 && *str2)
	{
		if (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		else
		{
			return (*str1 - *str2);
		}
	}

	return (*str1 - *str2);
}

int main()
{
	char str1[] = "abcdefg";
	char str2[] = "abcdhjk";

	int ret = my_strcmp(str1, str2);
	if (ret == 0)
	{
		printf("str1 = str2\n");
	}
	else if (ret >0)
	{
		printf("str1 >str2\n");
	}
	else
	{
		printf("str1< str2\n");
	}
	return 0;
}

模擬實現memcpy

函數原型:void * memcpy ( void * destination, const void * source, size_t num );

原理:將source指向的內存塊中

?num個字節的內容復制到

?destination指向的內存塊中

?返回復制完成后的destination

一般情況下不能勝任重疊拷貝

也就是自己拷貝自己

模擬實現:

#include#include 

//模擬實現memcpy
void* my_memcpy(void* dest, void* src, size_t num)
{
	assert(dest && src);
	void* p = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		++(char*)dest;
		++(char*)src;
	}
	return p;
}

int main()
{
	//拷貝整型
	int arr[] = { 1,2,3,4,5 };
	int brr[] = { 6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_memcpy(arr,brr,8);
	int i = 0;
	for (i = 0; i< sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	//拷貝字符串
	char str1[] = "xxxxxxxxxx";
	char str2[] = "abcde";
	my_memcpy(str1, str2, 5);
	printf("%s\n", str1);

	return 0;
}

模擬實現memmove

函數原型:void * memmove ( void * destination, const void * source, size_t num );

原理:將source指向的內存塊中

?num個字節的內容復制到

?destination指向的內存塊中

?返回復制完成后的destination

?完全勝任重疊拷貝

?可以自己拷貝自己

模擬實現:

#include#include 

//模擬實現,memmove
//可實現重疊拷貝
//當destsrc時從后向前
//當dest=src時從前向后 從后向前

void* my_memmove(void* dest, void* src, size_t num)
{
	void* p = dest;
	assert(dest && src);
	if (dest >src)
	{
		dest = (char*)dest + num-1;
		src = (char*)src + num-1;
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest=(char*)dest-1;
			src=(char*)src-1;
		}
	}
	else
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			++(char*)dest;
			++(char*)src;
		}
	}
	return p;
}

int main()
{
	//拷貝整型
	int arr[] = { 6,7,8,9,10 };
	int brr[] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	my_memmove(arr, brr, 12);
	int i = 0;
	for (i = 0; i< sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	//拷貝字符串
	char str1[] = "yyyyyyyyyy";
	char str2[] = "abcdef";
	my_memmove(str1, str2, 4);
	printf("%s\n", str1);

	//重疊拷貝
	int prr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int s = sizeof(prr) / sizeof(prr[0]);
	my_memmove(prr + 5, prr, 12);
	int j = 0;
	for (j = 0; j< s; j++)
	{
		printf("%d ", prr[j]);
	}
	return 0;
}

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

當前標題:字符串+內存函數(C語言)-創新互聯
文章來源:http://newbst.com/article10/dgidgo.html

成都網站建設公司_創新互聯,為您提供服務器托管、建站公司網站策劃、外貿網站建設、用戶體驗外貿建站

廣告

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