真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

【C語言】常用庫函數(shù)-創(chuàng)新互聯(lián)

目錄

?? sizeof
?? strlen
?? strcpy
?? strncpy
?? strcmp
?? strncmp
?? strcat
?? strncat
?? strstr
?? strtok
?? streror
?? memcpy
?? memmove
?? memcmp

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的白云網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!sizeof

??sizeof準確的來講不是一個庫函數(shù),而是一個單目運算符。它的參數(shù)可以是數(shù)組、指針、類型、對象、函數(shù)等,用來計算一塊內(nèi)存的大小。如果是字符串,則用sizeof的時候計算結(jié)果是包含結(jié)束符‘\0’的,因為結(jié)束符也是占用空間的。
??sizeof是在編譯的時候就計算好了緩沖區(qū)的長度,因此不能拿來計算和返回動態(tài)分配的內(nèi)存大小。

實例:

#include#includeint main()
{int s[10] = {0 };
	char s1[] = "abcdef";
	char s2[10] = "abcdef";

	printf("%d\n", sizeof(s));//輸出40   
	//初始化數(shù)組指定數(shù)組大小10個元素,每個元素類型是int,所以輸出10*4=40
	printf("%d\n", sizeof(s1));//輸出7
	//初始化數(shù)組時沒有指定大小,實際看數(shù)組占多大內(nèi)存
	//abcdef占6個字節(jié),字符串初始化數(shù)組會默認攜帶一個'\0',所以大小為6+1=7
	printf("%d\n", sizeof(s2));//輸出10;
	//初始化數(shù)組時指定數(shù)組大小為10,每個元素是int,所以輸出10*1=10
	return 0;
}
strlen

計算字符串長度。該函數(shù)返回字符串的長度,從第一個字符開始,到結(jié)束符截止,但是不包括結(jié)束符。
注意返回值是一個無符號整形數(shù)據(jù)

庫函數(shù)中實現(xiàn)的strlen函數(shù): size_t strlen ( const char * str );
typedef unsigned int size_t;
size_t 表示無符號的整型

實例

int main()
{char s[] = "abcdef";
	int ret = strlen(s);
	printf("%d", ret);//輸出6
	return 0;
}

模擬實現(xiàn):

#include#include
//法1 遍歷
size_t my_strlen1(const char* str)
{assert(*str != NULL);
	int count = 0;
	while (*str != '\0')
	{str++;
		count++;
	}
	return count;
}
//法2 遞歸
size_t my_strlen2(const char* str)
{//assert(*str != NULL);
	if (*str != '\0') {return my_strlen2(str + 1) + 1;
	}
	else {return 0;
	}
}
//法3   指針-指針
size_t my_strlen3(const char* str)
{const char* start = str;
	assert(*str != '\0');
	while (*str != '\0')str++;
	return str - start;
}
int main()
{char s[50] = "adsljkfakdsfj";
	printf("%d\n", my_strlen1(s));//輸出13
	printf("%d\n", my_strlen2(s));//輸出13
	printf("%d\n", my_strlen3(s));//輸出13
	return 0;
}
strcpy

庫函數(shù)中實現(xiàn)的strcpy函數(shù): char * strcpy ( char * destination, const char * source );
?
opies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point)
將源指向的C字符串復(fù)制到目標指向的數(shù)組中,包括終止空字符(并在該點停止)
?
為避免溢出,目標指向的數(shù)組的大小應(yīng)足夠長,以包含與源相同的 C 字符串(包括終止空字符),并且不應(yīng)在內(nèi)存中與源重疊

實例:

int main()
{char s[50] = "asdfh";
	char s1[20] = "dfajslk";
	char* ret = strcpy(s, s1);//會返回一個地址
	printf("%s", ret);//輸出dfajslk
	return 0;
}

模擬實現(xiàn):

#include#include
char* my_strcpy(char* dest, const char* src)
{assert(dest && src);
	char* ret = dest;
	while (*dest++ = *src++);
	return ret;
}
//模擬實現(xiàn)strcpy
int main()
{char s[50] = "asdfh";
	char s1[20] = "dfajslk";
	char* ret = my_strcpy(s, s1);
	printf("%s", ret);//輸出dfajslk
	return 0;
}
strncpy

??函數(shù)定義:char * strncpy ( char * destination, const char * source, size_t num );
??將源的第一個字符數(shù)復(fù)制到目標。如果在復(fù)制 num 個字符之前找到源 C 字符串的末尾(由 null 字符表示),則目標將填充零,直到總共寫入 num 個字符為止。
??如果源長度超過 num,則不會在目標末尾隱式附加空字符。因此,在這種情況下,不應(yīng)將目標視為以空結(jié)尾的 C 字符串(這樣讀取它會溢出)。
復(fù)制指針source 指向的內(nèi)存中的前num個字符到指針destination指向的內(nèi)存塊,包括結(jié)束符。
??如果num個數(shù)大于source的字符個數(shù),則依然復(fù)制num個字符,多的那部分填充’\0’ 。
??如果num個數(shù)少于source的字符的個數(shù),則字符串destination不是以結(jié)束符結(jié)尾,此??時如果訪問字符串destination可能會導(dǎo)致溢出,應(yīng)該手動填充結(jié)束符。

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char s1[] = "asdhkjadsg";
	char s2[50];

	char* ret = strncpy(s2, s1,5);
	*(ret + 5) = '\0';//手動添加結(jié)束標志
	printf("%s\n", ret);//輸出asdhk
	printf("%s\n", s2);//輸出asdhk
	return 0;
}
strcmp

??函數(shù)定義: int strcmp ( const char * str1, const char * str2 );
??比較兩個字符串,從字符串的首位開始比較起,如果他們相等,則依次往后,直到遇到不相同的字符,或直到結(jié)束符。如果字符串1和字符串2相等,則返回0,如果str1小于str2,則返回負數(shù),如果str1大于str2,則返回正數(shù)。

實例:

int main()
{char s1[] = "asdfjz";
	char s2[] = "asdfjh";
	int ret = strcmp(s1, s2);
	printf("%d", ret);//輸出1
	return 0;
}

模擬實現(xiàn):

#include#include
//模擬實現(xiàn)strcmp
int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);
	//判斷首字符是否相同,若是相同進入while循環(huán)繼續(xù)判斷下一個
	while (*str1 == *str2)
	{if (*str1 == '\0')//當(dāng)兩個字符串遍歷完仍然相同時
		{	return 0;//返回0表示兩個字符串相同
		}
		str1++; str2++;
	}
	//判斷大小
	if (*str1 >*str2)return 1;
	else return -1;
}

int main()
{char s1[] = "asdfjz";
	char s2[] = "asdfjh";
	int ret = my_strcmp(s1, s2);
	printf("%d", ret);//輸出1
	return 0;
}
strncmp

??函數(shù)聲明:int strncmp ( const char * str1, const char * str2, size_t num );
??將 C 字符串 str1 的字符數(shù)與 C 字符串 str2 的字符數(shù)進行比較。
??此函數(shù)開始比較每個字符串的第一個字符。如果它們彼此相等,則繼續(xù)使用以下對,直到字符不同,直到達到終止的空字符,或者直到兩個字符串中的 num 字符匹配,以先發(fā)生者為準

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char s1[] = "abcdefgg";
	char s2[] = "abcdefgh";
	int ret = strncmp(s1, s2,8);
	if (ret >0)
	{printf("s1 >s2\n");
	}else if(ret==0)
	{printf("s1 = s2");
	}
	else {printf("s1< s2");
	}
	return 0;//輸出 s2 >s1
}

模擬實現(xiàn):

#include#include#include

int my_strncmp(const char* str1, const char* str2, int num)
{assert(str1 && str2);
	while (*str1 == *str2)
	{while (num>0)
		{	if (*str1 == *str2)//如果兩個指針解引用指向的字符相同,就迭代往后走
			{		str1++; str2++;
			}
			else {//如果碰到不同的,則返回兩個字符之間的差
				return *str1 - *str2;
			}
			num -- ;
		}
		if (num == 0)
		{	return 0;
		}
	}
	return  *str1 - *str2;
}

int main()
{char str1[] = "abcde";
	char str2[] = "abcdf";
	int ret = my_strncmp(str1, str2, 4);
	int ret1 = my_strncmp(str1, str2, strlen(str2));
	printf("%d\n", ret);
	printf("%d\n", ret1);
	return 0;
}
strcat

??函數(shù)聲明:char * strcat ( char * destination, const char * source );
??連接字符串。將指針source 指向的字符串連接在指針destination指向的字符串后面,并且原來字符串的結(jié)束符會被source的首字符覆蓋掉,surce的結(jié)束符也會轉(zhuǎn)移過去,成為形成的新的字符串的結(jié)束符。
??連接成功則返回dset的首地址,失敗則返回空指針。

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char s1[20] = "asd";
	char* ret = strcat(s1, "hhl");//將字符串"hhl"追加到s1后面
	if (ret != NULL) 
	{printf("%s\n", ret);//輸出 asdhhl
	}
	else {printf("沒有追加成功\n");
	}
	return 0;
}

模擬實現(xiàn):

#include#include

char* my_strcat(char* dest, const char* src)
{assert(dest && src);
	char* ret = dest;
	//1.找到目標空間的\0
	while (*dest != '\0')dest++;
	//2.追加
	while (*dest++ = *src++) {;
	}
	return ret;
}

int main()
{char s[50] = "dsal";
	char s1[] = "daskf";
	char* ret = my_strcat(s, s1);
	printf("%s",ret);//輸出dsaldaskf
	return 0;
}
strncat

??函數(shù)聲明:char * strncat ( char * destination, const char * source, size_t num );
?
??將指針source 指向的字符串的num個連接在指針destination指向的字符串后面,并且原來字符串的結(jié)束符會被source的首字符覆蓋掉,

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char s1[20] = "adas";
	char s2[] = "hh";
	char* ret = strncat(s1, s2, sizeof(s2));
	printf("%s", ret);//輸出adashh
	return 0;
}

模擬實現(xiàn):

#include#include
#includechar* my_strncat(char* dest, const char* src, int size_t)
{assert(dest && src);
	char* ret = dest;

	while (*dest != '\0')dest++;
	while (size_t-- >0)//size_t=3
	{if (*src == '\0') {	//如果src指向的字符串不夠size_t賦值長度,則補0
			*dest = 0;
			dest++;
		}
		else {	//把src中的字符放入到dest中
			*dest = *src;
			dest++; src++;
		}
		*dest ='\0';//手動補字符串結(jié)束標志
	}
	return ret;//返回dest字符串起始地址
}

int main()
{char str1[20] = "abcd";
	char str2[] = "efg";
	char* ret = my_strncat(str1, str2, strlen(str2));
	puts(ret);
	return 0;
}
strstr

??函數(shù)聲明:*char * strstr ( const charstr1, const char * str2);
?
??定位子字符串返回指向 str1 中第一次出現(xiàn)的 str2 的指針,如果 str2 不是 str1 的一部分,則返回空指針。

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char s1[20] = "adasadsdf";
	char s2[] = "asad";
	char* ret = strstr(s1, s2);   //返回s2在字符串s1中首次出現(xiàn)的位置
	printf("%s", ret);   //輸出asadsdf
	return 0;
}

模擬實現(xiàn):

#include#include
//模擬實現(xiàn)strstr
char* my_strstr(const char* str1, const char* str2)
{const char* s1 = str1;
	const char* s2 = str2;
	const char* cp = s1;
	while (*cp) //判斷當(dāng)前指針cp指向的位置的字符是不是結(jié)束標志,如果不是,繼續(xù)進入循環(huán)
	{s1 = cp;
		s2 = str2;
		while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
		//字符串s1不結(jié)束,s2不結(jié)束,并且*s1跟*s2指向的字符相同,遍歷往后走
		{	s1++; s2++;
		}
		if (*s2 == '\0') //如果字符串s2遍歷完依舊沒有跳出循環(huán),表示s2在字符串s1中出現(xiàn)
		{	return cp;//返回當(dāng)前位置
		}
		cp++;//當(dāng)前指針向后遍歷
	}
	return NULL;
}

int main()
{char s[] = "adafassb";
	char s1[] = "sb";
	printf("%s", my_strstr(s, s1));
	return 0;
}
strtok

??函數(shù)聲明:char * strtok ( char * str, const char * sep );
??
??對此函數(shù)的一系列調(diào)用將 str 拆分為標記,這些標記是由分隔符中的任何字符分隔的連續(xù)字符序列。
在第一次調(diào)用時,該函數(shù)需要一個 C 字符串作為 str 的參數(shù),其第一個字符用作掃描令牌的起始位置。在后續(xù)調(diào)用中,該函數(shù)需要一個空指針,并使用最后一個令牌末尾之后的位置作為掃描的新起始位置。
??
??為了確定標記的開頭和結(jié)尾,該函數(shù)首先從起始位置掃描分隔符中未包含的第一個字符(該字符將成為標記的開頭)。然后從令牌的開頭開始掃描分隔符中包含的第一個字符,該字符將成為令牌的末尾。如果找到終止空字符,掃描也會停止。
??
??令牌的此結(jié)尾將自動替換為空字符,并且令牌的開頭由函數(shù)返回。
??一旦在對 strtok 的調(diào)用中找到 str 的終止空字符,則對此函數(shù)的所有后續(xù)調(diào)用(以空指針作為第一個參數(shù))都將返回空指針。
??找到最后一個令牌的點由要在下一次調(diào)用中使用的函數(shù)在內(nèi)部保留(不需要特定的庫實現(xiàn)來避免數(shù)據(jù)爭用)。

實例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#includeint main()
{char arr[] = "Tzhenchuan@yeah.net";
	char* p = "@.";
	char* ret = NULL;
	for (ret = strtok(arr, p);ret != NULL; ret = strtok(NULL, p))
	{printf("%s\n", ret);
	}
	//		輸出
	//		Tzhenchuan   
	//		yeah   
	//		net
	return 0;
}
streror

??函數(shù)聲明:char * strerror ( int errnum );
?
??調(diào)用函數(shù)strerror時,如果程序有錯誤就會產(chǎn)生一個錯誤碼存放在errno中,使用函數(shù)sererror就可以打印出程序所報錯誤的類型

案例:

#define _CRT_SECURE_NO_WARNINGS 1
#include#include#include//fopen()函數(shù)如果打開文件成功,就會返回一個有效的指針
//			 如果打開失敗,就會返回一個空(NULL)指針

int main()
{//打開文件    打開的是當(dāng)前目錄下面的文件   打開方式是r
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{printf("%s\n",strerror(errno));
		//輸出No such file or directory
		//錯誤信息是沒有這個文件或者文件夾
		return 1;
	}
	fclose(pf);
	pf = NULL;
	return 0;
}
memcpy

??函數(shù)定義:void * memcpy ( void * destination, const void * source, size_t num );
?
??函數(shù)memcpy從source的位置開始向后復(fù)制num個字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。
??這個函數(shù)在遇到 ‘\0’ 的時候并不會停下來。
??如果source和destination有任何的重疊,復(fù)制的結(jié)果都是未定義的

實例:

int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = {0 };
	memcpy(arr2, arr1, 20);
	for (int i = 0; i< 10; i++)
	{printf("%d ", arr2[i]);
	}//輸出結(jié)果:1 2 3 4 5 0 0 0 0 0
	return 0;
}

模擬實現(xiàn):

#include#include

void* my_memcpy(void* dest, const char* src,size_t num)
{//設(shè)計函數(shù)的時候為了使得傳入的數(shù)據(jù)兼容,采用void*指針接受可以兼容傳入的指針
//將void*指針統(tǒng)一強轉(zhuǎn)成(char*)指針進行操作,參數(shù)傳入的num實際上表示要改變多少個字節(jié)的值
	void* ret = dest;//存放要返回的地址
	assert(dest && src);
	while (num-- )//循環(huán)num次
	{*(char*)dest = *(char*)src;//將void*類型強轉(zhuǎn)成char*并對其所指向的內(nèi)存進行賦值
		dest = (char*)dest + 1;//由于dest跟src指針強轉(zhuǎn)只是暫時的,不能進行自增操作
		src = (char*)src + 1;//采用表達式的方式進行對dest和src指針的增操作
	}
	return ret;
}

int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9 };
	int arr2[10] = {0 };
	my_memcpy(arr2, arr1 + 2, 20);

	return 0;
}
memmove

??函數(shù)聲明:void * memmove ( void * destination, const void * source, size_t num );
?
??和memcpy的差別就是memmove函數(shù)處理的源內(nèi)存塊和目標內(nèi)存塊是可以重疊的。
??如果源空間和目標空間出現(xiàn)重疊,就得使用memmove函數(shù)處理
??
??移動內(nèi)存塊將數(shù)字字節(jié)的值從源指向的位置復(fù)制到目標所指向的內(nèi)存塊。

實例:

#include#include

int main()
{int s[] = {1,2,3,4,5,6,7,8,9 };
	memmove(s+2, s, 20);//數(shù)組內(nèi)容變?yōu)?1,2,1,2,3,4,5,8,9
	//從s數(shù)組第三個元素開始改為數(shù)組s第一個元素開始的5個元素    內(nèi)存重疊
	return 0;
}

模擬實現(xiàn):

#include#include

void* my_memmove(char* dest, const char* src, size_t num)
{assert(dest && src);
	//為了使內(nèi)存重疊時也能進行操作,判斷dest和src指針的位置進行兩種不同的方式進行賦值操作
	//memcpy原先設(shè)計的時候在內(nèi)存重疊的時候操作會出錯,memmove可以說是memcpy的改進版
	if (dest< src)
	{while (num--) {	*(char*)dest = *(char*)src;//同上一個函數(shù)my_memcpy原理一樣
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else {while (num--)
		{	*((char*)dest + num) = *((char*)src + num);
		}
	}
}

int main()
{int s[] = {1,2,3,4,5,6,7,8,9 };
	my_memmove(s+2, s, 20);
	return 0;
}
memcmp

??函數(shù)聲明:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
??
??將 ptr1 指向的內(nèi)存塊的前 num 字節(jié)數(shù)與 ptr2 指向的第一個字節(jié)數(shù)進行比較,如果它們都匹配,則返回零,如果不匹配,則返回一個不同于零的值,表示哪個值更大。 請注意,與 strcmp 不同,該函數(shù)在找到空字符后不會停止比較

實例:

#include#includeint main()
{char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";
	int n;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));
	//比較兩個字符串,返回一個值表示兩個字符串的大小關(guān)系
	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);
	}
	//輸出'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'
	return 0;
}

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


文章名稱:【C語言】常用庫函數(shù)-創(chuàng)新互聯(lián)
文章分享:http://weahome.cn/article/ddjjgs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部