1.函數(shù)原型
size_t strlen(const char *string );
我們也可以打開MSDN查看他的原型
?2.函數(shù)功能:求一個(gè)字符串指定string字符串的長度
3.strlen函數(shù)的實(shí)現(xiàn):
實(shí)現(xiàn)的思想是這樣的我們只要讓一個(gè)指針指向字符串的起始位置,讓他一直往后走直到遇到/0就停止在上述過程中用計(jì)數(shù)器count統(tǒng)計(jì)str走了多少步,count的值就是這個(gè)字符串的長度了
說明:
strlen() 函數(shù)計(jì)算的是字符串的實(shí)際長度,遇到第一個(gè)’/0’結(jié)束;
參數(shù)指向的字符串必須以 ’ /0 ‘結(jié)束
函數(shù)返回值一定是size_t ,是無符號的
如果你只定義沒有給它賦初值,這個(gè)結(jié)果是不定的,它會從首地址一直找下去,直到遇到’/0’停止
sizeof返回的是變量聲明后所占的內(nèi)存數(shù),不是實(shí)際長度,此外sizeof不是函數(shù),僅僅是一個(gè)操作符,strlen()是函數(shù)
這是特別要注意的?。。。。。。。。。。。。。。。。。。。。。。。。。。。。?/p>
代碼實(shí)現(xiàn):
#include#includeint my_strlen(const char* str)//我們只是要求一下他的長度并不會修改他所以加const保護(hù)字符串{ assert(str);//斷言防止str為空指針 int count = 0; while (*str!="/0") { str++; count++;//計(jì)數(shù) } return count;}int main(){ char arr[] = "abcd"; int ret=my_strlen(arr); printf("%d", ret);}
?方法2:遞歸方法(重點(diǎn),以后面試可能會問到)
#include#includeint my_strlen(const char* str)//我們只是要求一下他的長度并不會修改他所以加const保護(hù)字符串{ assert(str);//斷言防止str為空指針 if (*str) { return 1 + my_strlen(++str); } else { return 0; }}int main(){ char arr[] = "abcd"; int ret=my_strlen(arr); printf("%d", ret);}
方法3:指針減指針
#include#includeint my_strlen(const char* str)//我們只是要求一下他的長度并不會修改他所以加const保護(hù)字符串{ assert(str);//斷言防止str為空指針 const char* start = str; const char* end = str; while (*end != "/0") { end++; } return end - start;}int main(){ char arr[] = "abcdf"; int ret=my_strlen(arr); printf("%d", ret);}
1.函數(shù)原型:
?2.函數(shù)功能:將參數(shù)str字符串拷貝到參數(shù)dest所指向的字符串的地址中.注入事項(xiàng):strcpy拷貝的時(shí)候是要拷貝到"/0"才停止拷貝。所以一定要保證目的地空間足夠大.我strcpy的脾氣就是我要拷貝到‘/0"我才停止你空間足不足夠我才不關(guān)心,我只負(fù)責(zé)拷貝其他的我不管。
說明:
? ?1.? 源字符串必須以’/0’結(jié)束
? 2. 會將源字符串的’/0’拷貝到目標(biāo)空間
? 3.目標(biāo)空間必須可變
? 4. 如果參數(shù)dest所指的內(nèi)存空間不夠大,可能會造成緩沖溢出的錯(cuò)誤情況,在編寫程序時(shí)需特別留意,或者用strncpy()來取代
#include#includeint main(){ char arr1[] = "abcdef"; char arr2[] = "abc";char *ret=strcpy(arr2, arr1);printf(ret);}
在這個(gè)實(shí)驗(yàn)中我們把a(bǔ)rr1的內(nèi)容拷貝到arr2中但是arr2中的空間只有4個(gè)字節(jié)而arr1是有7個(gè)字節(jié),我們一起來看一下啊運(yùn)行結(jié)果:
?我們可以看到雖然字符串a(chǎn)rr1被拷貝到arr2中去了但此時(shí)程序已經(jīng)崩潰了。所以我們在使用strcpy時(shí)一定要確保目的地空間足夠大。
3.代碼實(shí)現(xiàn):
#include#includechar* my_strcpy(char* dest, const char* src){ assert(dest && src);//防止dest和src為空指針 char* ret = dest; while (*src) { *dest = *src; dest++; src++; } *dest = *src;//將src中的’/0"拷貝到dest中 return ret;}int main(){ char arr1[] = "abcdef"; char arr2[] = "abv"; char*ret=my_strcpy(arr1, arr2); printf(ret);}
運(yùn)行結(jié)果:
?拷貝前:
拷貝后:
在上面這個(gè)版本上我們還可以進(jìn)行改進(jìn):
#include#includechar* my_strcpy(char* dest, const char* src){ assert(dest && src);//防止dest和src為空指針 char* ret = dest; while (*dest++ = *src++) ; return ret;}int main(){ char arr1[] = "abcdef"; char arr2[] = "abv"; char*ret=my_strcpy(arr1, arr2); printf(ret);}
1.函數(shù)原型:
2.函數(shù)功能:
字符串進(jìn)行比較
我們通過文檔我們可以知道:如果第一個(gè)字符串小于第二個(gè)返回的是小于0的數(shù)如果第一個(gè)字符串等于第二個(gè)返回的·是0如果第一個(gè)字符串大于第二個(gè)字符串返?回的是大于0的數(shù)字
原型:strcmp(str1,str2);
功能:比較兩個(gè)字符串,如果兩個(gè)字符串相等,則返回0;若str1大于str2(對于大于的理解,是指從兩個(gè)字符串的第一個(gè)字符開始比較,若兩個(gè)字符相同,則繼續(xù)比較,若發(fā)現(xiàn)兩個(gè)字符不相等,且str1中該字符的ASCII碼大于str2中的,則表示str1大于str2),返回一個(gè)正數(shù)(這個(gè)正數(shù)不一定是1);若str1小于str2,返回一個(gè)負(fù)數(shù)(不一定是-1);若字符串str1的長度大于str2,且str2的字符與str1前面的字符相同,則也相對于str1大于str2處理
區(qū)分大小寫比較的,如果希望不區(qū)分大小寫進(jìn)行字符串比較,可以使用stricmp函數(shù)
?首先判斷第一個(gè)字符是否相等如果相等直接繼續(xù)往后走直到兩個(gè)不相等
3.代碼實(shí)現(xiàn):
#includeint my_strcmp(const char* dest, const char* src){ assert(dest&&src); while (*dest == *src) { if (*dest == "/0")//如果dest等于‘/0"說明這兩個(gè)字符串相等相等返回0 { return 0; } dest++; src++; } return *dest - *src;//說明這兩個(gè)字符串不相等,返回他們第一不相等字符的差值}int main(){ char str1[] = "abcde"; char str2[] = "abcdrq"; int ret = my_strcmp(str1, str2); printf("%d", ret);}
1.函數(shù)聲明原型
?2.函數(shù)功能:字符串拼接函數(shù)
實(shí)現(xiàn)思路大致是:先找到dest’/0"的位置,然后從該位置將str中的內(nèi)容向后面追加
追加前:
追加后:
?我們也可以調(diào)試看到:
注意!
1.源字符串必須’/0’結(jié)束
2. 目標(biāo)空間必須可修改
3.strcat() 會將參數(shù)src字符串復(fù)制到參數(shù)dest所指的字符串尾部
4.dest最后的結(jié)束字符’/0’會被覆蓋掉,并在連接后的字符串的尾部再增加一個(gè)’/0’
5.dest與src所指的內(nèi)存空間不能重疊,且dest要有足夠的空間來容納要復(fù)制的字符串
6.所以不能夠自己給自己拷貝因?yàn)椤?0"已經(jīng)被覆蓋了而strcat是要追加到‘/0"才停止追加?。。。。。。?/p>
代碼實(shí)現(xiàn):
#include#include#includechar* my_strcat(char* dest, const char* src){ assert(dest && src); char* ret = dest; while (*dest) { dest++;//找到dest所指向的字符串"/0’的位置 } while (*dest++ = *src++) ; return ret;}int main(){ char str1[] = "abcded/0XXXXXXX"; char str2[] = "abc"; my_strcat(str1, str2); printf("%s", str1); return 0;}
1.函數(shù)原型
2.函數(shù)功能:
功能:在str字符串中查找首次出現(xiàn)字符c的位置(從字符串的首地址開始查找)
原型2:strrchr(str,c);
功能2:在字符串str中從后向前開始查找字符c首次出現(xiàn)的位置
3.代碼實(shí)現(xiàn):
#include#includechar* my_strchr(const char* str, int ch){ assert(str); char* ret = (char*)str; while (*ret) { if (*ret ==(char) ch) { return ret; } ret++; } return NULL;}int main(){ char str[] = "abcdefhfmg"; char* tmp = my_strchr(str, "0"); if (tmp == NULL) { printf("找不到"); return 0; } printf("%c", *tmp);}
1.函數(shù)原型:
?2。函數(shù)功能:
查找一個(gè)字符c在一個(gè)字符串string最后一次出現(xiàn)的位置(也就是從字符串的右側(cè)開始查找字符c首次出現(xiàn)的位置)并返回從字符串中的字符c所在的位置開始直到結(jié)束的所有字符,如果沒有找到字符c則返回空指針即NULL
3.代碼實(shí)現(xiàn):
#include#includechar* my_strrchr(const char* str,int ch){ assert(str); char* ret = NULL; while (*str) { if (*str == (char)ch) { ret = str; } str++; } return ret;}int main(){ char str[] = "abcdeabcef"; char* tmp = my_strrchr(str, "a"); printf(tmp);}
1.函數(shù)原型:
2.函數(shù)功能
功能:將字符串str2中的前n個(gè)字符復(fù)制到字符串str1的前n個(gè)字符中
注意:(1)不會清除str1中全部字符串,只會改變前n個(gè)字符串,
(2)n不能大于字符串str1、str2的長度
(3)但是如果使用strncpy_s便會清除str1中的全部字符串
說明:
- 如果src字符串長度小于n,則拷貝完字符串后,在目標(biāo)后追加0,直到num個(gè)
- strncpy不會向dest追加’/0’
- src和dest所指的內(nèi)存區(qū)域不能重疊,且dest必須有足夠的空間放置n個(gè)字符
3.代碼實(shí)現(xiàn)
#include#include#includechar* my_strncpy(char* dest, const char* src, int n){ assert(dest && src); char* tmp = dest; while ((n--) && (*dest++ = *src++)); if (n > 0) { while (n--) { *dest++ = "/0"; } } return tmp;}int main(){ char str1[] = "abcdeXXXXXXXXXXXX"; char str2[] = "avcdf"; char* ret =my_strncpy(str1, str2, 6); return 0;}
雖然比strncpy要安全一點(diǎn)但還是要注意要保證目的地空間足夠
1.函數(shù)原型:
?函數(shù)功能:
該函數(shù)會將字符串src的開頭拷貝n個(gè)字符到dest的尾部,dest要有足夠的空間來容納要拷貝的字符串,如果n大于src的長度,那么只會把src僅有的字符串內(nèi)容追加到dest的尾部。strncat會將dest里面的‘/0’覆蓋掉字符追加完畢后自動加一個(gè)‘/0"
也就相當(dāng)于這樣:
我們在上面那個(gè)長的字符串從下面這個(gè)字符串中追加2個(gè)字符那么結(jié)果將為:
通過調(diào)試我們也能夠證明上面這個(gè)是對的:
如果追加3個(gè)字符那么結(jié)果和上面是一樣的。大家可以做實(shí)驗(yàn)驗(yàn)證
注意!?。。?!
- strncat將會從字符串src的開頭拷貝n個(gè)字符到dest字符串尾部
- dest要有足夠的空間來容納要拷貝的字符串
- 如果n大于字符串src的長度,那么僅將src全部追加到dest的尾部
- strncat會將dest字符串最后的’/0’覆蓋掉,字符追加完成后,再追加’/0’
代碼實(shí)現(xiàn):
#include#include#includechar* my_strncat(char* dest, const char* src, int n){ assert(dest && src); char* ret = dest; while (*dest) { ++dest; } for (int i = 0; i < n; i++) { if (*src) { *dest = *src; dest++; src++; } else { break; } } *dest = "/0"; return ret;}int main(){ char str1[] = "abcde/0XXXXXX"; char str2[] = "avbv"; strncat(str1, str2, 2); return 0;}
1.函數(shù)原型:
2.函數(shù)功能:strncmp的功能和strcmp的功能和相似,只不過多了一個(gè)參數(shù)用來確定比較的個(gè)數(shù)
3。代碼實(shí)現(xiàn):
#include#include#includeint my_strncmp(const char* dest, const char* src, int n){ assert(dest && src); while ((n--) && (*dest) && (*src) && (*src == *dest)) { src++; dest++; } return *dest - *src;}int main(){ char str1[] = "abcdef"; char str2[] = "abcf"; int ret = my_strncmp(str1, str2, 2); printf("%d", ret);}
函數(shù)原型:
?2.函數(shù)功能:
在字符串中找子串原理是string中是否包含strcharset如果包含就返回第一個(gè)出現(xiàn)字符的地址,如果沒有就返回空指針
3.代碼實(shí)現(xiàn)。
#include#includechar* my_strstr(const char* dest, const char* src){ assert(dest && src); if (!*src) { return (char*)dest; } const char* cur =dest; const char* s1; const char* s2; s1 = s2 = NULL; while (cur) { s1 = cur; s2 = src; while ((*s1) && (*s2) && (*s1 == *s2)) { s1++; s2++; } if (*s2 == "/0") { return (char*)cur; } cur++; } return NULL;//找不到字串}int main(){ char str1[] = "abcdef"; char str2[] = "bcdef"; printf(my_strstr(str1, str2));}
1.函數(shù)原型:
2.函數(shù)功能:
功能:根據(jù)分隔符將字符串分隔成一個(gè)個(gè)片段
返回值:返回下一個(gè)分割后的字符串指針,如果已無從分割則返回NULL
說明:
1.sep參數(shù)是個(gè)字符串,定義了用作分隔符的字符集合
2.第一個(gè)參數(shù)指定一個(gè)字符串,它包含了一個(gè)或者多個(gè)由sqp字符串中一個(gè)或者多個(gè)字符分割的標(biāo)記
3.第一次調(diào)用時(shí)將字符串首地址傳進(jìn)去,之后調(diào)用不用傳地址,內(nèi)部會有static函數(shù)保存指向地址
4.分隔符不作為輸出內(nèi)容,只做分界符
5. 當(dāng)strtok在參數(shù)s的字符串中發(fā)現(xiàn)到參數(shù)sep的分割字符時(shí)則會將該字符改為’/0’字符
6. 在第一次調(diào)用時(shí),strtok必須賦予參數(shù)str字符串,往后的調(diào)用則將參數(shù)s設(shè)置成NULL
7.strtok會修改原字符串,所以必須放至棧上
代碼實(shí)現(xiàn):
char* strtok1(char* str, const char* sep){ static int ret = 0;//這個(gè)靜態(tài)變量也十分重要!當(dāng)指針指向最后一個(gè) 字符串str 出現(xiàn)的 sep字符分隔符, //因?yàn)樽詈笠欢巫址⒉粫俪霈F(xiàn)sep中任何一個(gè)分隔符,所以字符串就不會打印, //那我們?nèi)绾螀^(qū)分這種情況和str中就從來沒有出現(xiàn)過sep字符的情況,我們設(shè)置一個(gè)靜態(tài)變量,如果靜態(tài)變量被修改過,就輸出字符串,如果沒修改過就返回空指針。 static char* a = NULL; //這里要用到靜態(tài)變量,這樣函數(shù)結(jié)束變量就不會銷毀,a會記住上一次的地址 if (str != NULL) // 判斷是否為NULL { a = str; ret = 0; } else { if (ret == 2) return NULL; a++; } char* first = a; while (*a) { const char* p = sep; while (*p) { if (*p == *a) { *a = "/0"; ret = 1; return first; } p++; } a++; if (*a == "/0") { ret = 2; break; } } if (ret == 0) return NULL; else if(ret == 2) return first;}
其實(shí)這里還有一些函數(shù)博主就不一 一實(shí)現(xiàn)就在這里簡單的介紹一個(gè)就可以了
函數(shù)名稱 | 函數(shù)原型 | 函數(shù)功能 |
strerro | char*strerro(int errnom) | 1.返回錯(cuò)誤碼,所對應(yīng)的錯(cuò)誤信息 2使用庫函數(shù)調(diào)用失敗的時(shí)候,都會設(shè)置錯(cuò)誤碼并存儲在errno中 |
strpbrk | char* strpbrk(const char* str1, const char* str2) | 在字符串s1中尋找字符串s2中任何一個(gè)字符相匹配的第一個(gè)字符的位置,空字符NULL不包括在內(nèi) |
strcspn | size_t strspn(const char* str1, const char* str2) | 功能:用來計(jì)算str1字符串開始部分不匹配str2字符串的字符個(gè)數(shù) 返回字符串str1開頭部分不出現(xiàn)在字符串str2內(nèi)的字符數(shù)目。 |
strspn | size_t strspn(const char* str1, const char* str2) | 功能:用來計(jì)算str1字符串開始部分匹配str2字符串的字符個(gè)數(shù) 返回字符串str1開頭連續(xù)包含字符串str2內(nèi)的字符數(shù)目 |
函數(shù)名稱 | 函數(shù)原型 | 函數(shù)功能 |
atoi | int atoi(const char* str) | 功能:將字符串轉(zhuǎn)換成整型 返回轉(zhuǎn)換后的整型數(shù)。如果str不能轉(zhuǎn)換成int或者str為空字符串,那么將返回0 |
atof | double atof( const char *string ) | 將字符串轉(zhuǎn)換成浮點(diǎn)型 |
atol | long atol( const char *string ) | 將字符串轉(zhuǎn)換成浮點(diǎn)型 |
gcvt | char *_gcvt( double value, int digits, char *buffer ) | 將浮點(diǎn)型轉(zhuǎn)成字符串 |
itoa | char *_itoa( int value, char *string, int radix ) | 將整型轉(zhuǎn)換成字符串 |
? ? ? ? ? ? ? ? ? ? ? ? ?
函數(shù)名稱 | 函數(shù)原型 | 函數(shù)功能 |
strtod | double strtod( const char *nptr, char **endptr ) | 字符串轉(zhuǎn)換成浮點(diǎn)型 |
strtol | long strtol( const char *nptr, char **endptr, int base ); | 將字符串轉(zhuǎn)換成長整型 |
strtoul | unsigned long strtoul( const char *nptr, char **endptr, int base ); | 將字符串轉(zhuǎn)換成無符號長整型 |
toascii | int __toascii( int c ) | 將整型轉(zhuǎn)成合法的ASSll碼字符 |
_itot_s | errno_t?_itoa_s(int?value,?char?*buffer,?size_t?sizeInCharacters,?int?radix); ? | 將int轉(zhuǎn)換成char* |
_ttoi | 可以將Cstring 轉(zhuǎn)成整型 |
int atoi(const char* str)
2.函數(shù)功能
將字符串轉(zhuǎn)換成整數(shù)
注意:
返回值:每個(gè)函數(shù)返回?int?值,此值由將輸入字符作為數(shù)字解析而生成。?如果該輸入無法轉(zhuǎn)換為該類型的值,則atoi的返回值為?0。
工作原理:atoi通過全局變量來區(qū)分返回0的情況。
如果是非法輸入,返回0,并把這個(gè)全局變量設(shè)為特殊標(biāo)志;
如果輸入是”0”,則返回0,不會設(shè)置全局變量。
使用該函數(shù)時(shí)要注意atoi返回的是int類型,注意輸入str的范圍不要超出int類型的范圍。
3.函數(shù)實(shí)現(xiàn):
#include#include#include#include#includeint my_atoi(const char* str){ assert(str); long long ret = 0; int flag = 1; if (!*str) { return 0; } while (isspace(*str)) { str++; } if (*str == "+") { str++; } else if (*str == "-") { flag = -1; str++; } while (isdigit(*str)) { ret = ret * 10 + *str - "0"; if (ret > INT_MAX || ret < INT_MIN)//超出整型最大說明溢出了 { return 0; } str++; } if (*str == "/0") { return (int)ret*flag; } return (int)flag*ret;}int main(){ int tmp = my_atoi("-123"); printf("%d", tmp);}
代碼實(shí)現(xiàn):
#include#includevoid my_reverse(char* str){ int right= strlen(str)-1; int left = 0; while (left
1.函數(shù)原型
double atof( const char *string )
2.函數(shù)功能
將字符串轉(zhuǎn)成浮點(diǎn)數(shù)
3.代碼實(shí)現(xiàn)
#include#include#includedouble my_atof(const char* str){ double ret = 0; int flag = 1; int count = 0; assert(str); while (isspace(*str)) { str++; } while (*str) { if (count) { count = count * 10; } if (*str == "+") { str++; } else if (*str=="-") { str++; flag = -1; } else if (*str == ".") { count++; str++; } else if ((*str>="0")&&(*str<="9")) { ret = ret * 10 + (double)(*str - "0"); str++; } else { return 0; } } return ret * flag / count;}int main(){ double tmp = my_atof("123.3abc"); printf("%.2lf", tmp);}
之前樓主遺漏了一些函數(shù)在這里補(bǔ)上
int isalnum(int c):檢查字符是否為數(shù)字或字母;(0~9,a~z,A~Z)?
int isalpha(int c):檢查字符是否為字母;(a~z, A~Z)?
int iscntrl(int c):檢查字符是否為控制字符;(八進(jìn)制000~037以及177的字符)?
int isdigit(int c):檢查字符是否為十進(jìn)制數(shù)字;(0~9)?
int isgraph(int c):檢查字符是否為圖形表示,依賴于使用語言的環(huán)境;0~9,a~z,A~Z,以及標(biāo)點(diǎn)符號)?
int islower(int c):檢查字符是否為小寫的字母;(a~z)?
int isprint(int c):檢查字符是否為可打印的;(數(shù)字、字母、標(biāo)點(diǎn)符號、空白字符)?
int ispunct(int c):檢查字符是否為標(biāo)點(diǎn)符號;(! ” # $ % & ’ ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~等)?
int isspace(int c):檢查字符是否為空白字符;(TAB、換行、垂直TAB、換頁、回車、空格)?
int isupper(int c):檢查字符是否為大寫字母;(A~Z)?
int isxdigit(int c):檢查字符是否為十六進(jìn)制數(shù)字;(0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f)?
字符串轉(zhuǎn)換函數(shù):
int tolower(int c):轉(zhuǎn)化字符為小寫字母;
int toupper(int c):轉(zhuǎn)化字符為大寫字母;
關(guān)于字符串的函數(shù)就到此結(jié)束
下面博主介紹幾個(gè)內(nèi)存操作函數(shù):
1.函數(shù)原型:
void *memcpy( void *dest, const void *src, size_t count )
2.函數(shù)功能
內(nèi)存拷貝,可以拷貝任意類型不考慮’/0’
功能:函數(shù)memcpy從src的位置開始向后復(fù)制count個(gè)字節(jié)的數(shù)據(jù)到dest的內(nèi)存位置
說明:
- 這個(gè)函數(shù)在遇到’/0’不會停下來
- 如果src與dest任何的重疊,復(fù)制結(jié)果都是未定義的
- 1.src和dest所指內(nèi)存區(qū)域不能重疊
2.與strcpy相比,memcpy遇到‘/0’并不會結(jié)束,而是一定會拷貝完n個(gè)字節(jié)
3.memcpy可以拷貝任何數(shù)據(jù)類型的對象,可以指定拷貝的數(shù)據(jù)長度
4.如果dest本身就有數(shù)據(jù),執(zhí)行memcpy()后會覆蓋原有的數(shù)據(jù)
5.dest和src都不一定時(shí)數(shù)組,任意的可讀寫的空間均可
6.如果要追加數(shù)據(jù),則每次執(zhí)行memcpy后,要將目標(biāo)數(shù)組地址增加到所要追加數(shù)據(jù)的地址
?
原理如下:
3.代碼實(shí)現(xiàn):
#include#includevoid* my_memcpy(void* dest, const void* src, int n){ assert(dest && src); void* ret = dest; while (n--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } return ret;}int main(){ int arr1[10] = { 0 }; int arr2[] = { 1,2,3,4,5 }; my_memcpy(arr1, arr2, 20); for (int i = 0; i < 10; i++) { printf("%d ", arr1[i]); } return 0;}
1.函數(shù)原型
int memcmp( const void *buf1, const void *buf2, size_t count )
2.函數(shù)功能
功能:比較內(nèi)存區(qū)域buf1和buf2的前count個(gè)字節(jié)。注意該函數(shù)是按字節(jié)比較的
返回值:
當(dāng)buf1 < buf2時(shí),返回值<0
當(dāng)buf1 = buf2時(shí),返回值=0
當(dāng)buf1 > buf2時(shí),返回值>0
3.代碼實(shí)現(xiàn)
#include#includeint my_memcmp(const void* str1, const void* str2, int num){ if (num == 0) { return 0; } assert(str1 && str2); char* s1 = (char*)str1; char* s2 = (char*)str2; while ((num--)&&(*s1==*s2)&&*s1&&*s2) { s1++; s2++; } return *s1 - *s2;}int main(){ int arr1[10] = { 1,2,3,4,5 }; int arr2[10] = { 5,2,3,5 }; int tmp = my_memcmp(arr1, arr2, 0); printf("%d", tmp);}
1.函數(shù)原型
void *memset( void *dest, int c, size_t count )
2.函數(shù)功能
功能:以str的起始位置開始的n個(gè)字節(jié)的內(nèi)存區(qū)域用整數(shù)value進(jìn)行填充
返回值:目標(biāo)str內(nèi)存起始地址
說明:按字節(jié)設(shè)置,進(jìn)行賦值1.memset用來對一段內(nèi)存空間全部設(shè)置為某個(gè)字符,一般用在對定義的字符串進(jìn)行初始化為‘ ’或‘/0’
2.如果用malloc分配的內(nèi)存,一般只能使用memset來初始化
3.memset可以方便的清空一個(gè)結(jié)構(gòu)類型的變量或數(shù)組,它可以一字節(jié)一字節(jié)地把整個(gè)數(shù)組設(shè)置為一個(gè)指定的值
4.當(dāng)結(jié)構(gòu)體類型中包含指針時(shí),在用memset初始化時(shí)需要特別小心這是因?yàn)楫?dāng)用memset初始化為0時(shí)會把指針初始化為NULL5.在使用memset給數(shù)組進(jìn)行初始化時(shí)我們只能將數(shù)組中的每一個(gè)元素初始話為0或者-1,應(yīng)為memset是一個(gè)字節(jié)一個(gè)字節(jié)進(jìn)行初始化
3.代碼實(shí)現(xiàn)
#include#includevoid* my_memset(void* dest, int val, int num){ assert(dest); char* s1 = (char*)dest; void* ret = dest; while (num--) { *s1 = (char)val; s1++; } return ret;}int main(){ int arr[10]; my_memset(arr, 0, 40); for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); }}
1.函數(shù)原型
void* memchr(const char* ptr ,int value,sizez_t num)
2.函數(shù)功能
功能:從buf所指內(nèi)存區(qū)域的前count個(gè)字節(jié)查找字符ch。
返回值:當(dāng)?shù)谝淮斡龅阶址鹀h時(shí)停止查找。如果成功,返回指向字符ch的指針;否則返回NULL
3.代碼實(shí)現(xiàn)
void* my_memchr(const void* dest, int c, int num){ assert(dest); char* ret = (char*)dest; while (num--) { if ((char)c == *ret) { return ret; } else { ret++; } } return NULL;}
1.函數(shù)原型
void*memmove(void *dest,const void*src,int num)
2.函數(shù)功能
用于內(nèi)存拷貝的函數(shù),沒有類型限制,但是memmove使用要考慮內(nèi)存重疊問題
void?*?memmove(void?*?destination,?const?void?*?source,?size_t?num);
用于從src中拷貝num個(gè)任意類型的內(nèi)容到dest,如果目標(biāo)區(qū)域和源區(qū)域有重疊(并不是所有重疊情況都需要特殊處理),memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標(biāo)區(qū)
3.代碼實(shí)現(xiàn)
void *my_memove(void* dest, const void* src, int num){ assert(dest && src); void* ret = dest; if(dest
最后介紹幾個(gè)數(shù)學(xué)函數(shù)
1.函數(shù)原型:
double sqrt( double x );
2.函數(shù)功能
計(jì)算一個(gè)非負(fù)實(shí)數(shù)的平方根
實(shí)現(xiàn)原理:
牛頓迭代法是一種可以用來快速求解函數(shù)零點(diǎn)的方法。
為了敘述方便,我們用 CC 表示待求出平方根的那個(gè)整數(shù)。顯然,CC 的平方根就是函數(shù)
y = f(x) = x^2 - C,y=f(x)=x?2??C的零點(diǎn)。
牛頓迭代法的本質(zhì)是借助泰勒級數(shù),從初始值開始快速向零點(diǎn)逼近。我們?nèi)稳∫粋€(gè)?x0??作為初始值,在
每一步的迭代中,我們找到函數(shù)圖像上的點(diǎn) (x_i, f(x_i))(x?i?,f(x?i?)),過該點(diǎn)作一條斜率為該點(diǎn)導(dǎo)數(shù) f"(x_i)f?′(x?i?) 的直線,與橫軸的交點(diǎn)記為 x_{i+1}x?i+1。x_{i+1}x?i+1相較于 x_ix?i?? 而言距離零點(diǎn)更近。在經(jīng)過多次迭代后,我們就可以得到一個(gè)距離零點(diǎn)非常接近的交點(diǎn)。下圖給了從 x_0x?0開始迭代兩次,得到 x_1x?1和 x_2x?2的過程。
?
代碼實(shí)現(xiàn):
int mySqrt(int x){long tmp = x; while (tmp*tmp > x) { tmp = (tmp + x/tmp) / 2; } return (int)tmp; }
1.函數(shù)原型
double pow( double x, double y )
2.函數(shù)功能
求a^b
原理:
?
代碼實(shí)現(xiàn)
double myPow(double x, int n) { if(x == 1 || n == 0) { return 1; } double tmp = 1; long count=n; if(n < 0){ count = -count; x = 1/x; } while(count) { if(count & 1) { tmp *= x; } x *= x; count>>= 1; } return tmp; }
1.函數(shù)原型:
int abs( int n )
2.函數(shù)功能
求絕對值
代碼實(shí)現(xiàn)
#includeint my_abs(int n){ int tmp = n >> 31; return (n ^ tmp) - tmp;}int main(){ int tmp = my_abs(10); printf("%d", tmp);}
最后博主在補(bǔ)充幾個(gè)數(shù)學(xué)函數(shù):
函數(shù)名稱 | 函數(shù)原型 | 函數(shù)功能 |
fabs() | double fabs(double x) | 求雙精度的絕對值 |
exp() | double exp(double x) | 求指數(shù)e^x的值 |
log10() | double log 10 (double x) | 求log 10 x的值 |
pow10(int p) | double pow10(int p) | 返回10^p的值 |
?ceil | double ceil(double x) | 求不小于x的最小整數(shù) |
floor | double floor(double x) | 求不大于x的最大整數(shù) |
博主水平有限如有錯(cuò)誤一定要向博主指出,一起進(jìn)步。前路昭然,你我共進(jìn)!?。?!
覺得寫的不錯(cuò)的可以點(diǎn)個(gè)贊 謝謝
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/119117.html
摘要:語言在設(shè)計(jì)中考慮了函數(shù)的高效性和易用性兩個(gè)原則。在語言中,最常見的當(dāng)屬函數(shù)了。以上就是一個(gè)函數(shù),它被稱為語言的入口函數(shù),或者主函數(shù)。例如和都是函數(shù)名。形式參數(shù)當(dāng)函數(shù)調(diào)用完成之后就自動銷毀了。 ...
摘要:形式參數(shù)當(dāng)函數(shù)調(diào)用完成之后就自動銷毀了。函數(shù)調(diào)用傳值調(diào)用函數(shù)的形參和實(shí)參分別占有不同內(nèi)存塊,對形參的修改不會影響實(shí)參。函數(shù)的聲明一般出現(xiàn)在函數(shù)的使用之前。它其實(shí)就數(shù)組訪問的操作符。 ...
摘要:本文介紹了類的常用接口的使用,并對其進(jìn)行了模擬實(shí)現(xiàn),對模擬實(shí)現(xiàn)中涉及到的深淺拷貝問題進(jìn)行了解析。在此之前,必須提到一個(gè)經(jīng)典問題。為了解決淺拷貝問題,所以中引入了深拷貝。但是實(shí)際使用中需要是第一個(gè)形參對象,才能正常使用。 本文介紹了string類的常用接口的使用,并對其進(jìn)行了模擬實(shí)現(xiàn),對模擬實(shí)...
摘要:指針變量可以存放基本類型數(shù)據(jù)的地址,也可以存放數(shù)組函數(shù)以及其他指針變量的地址。數(shù)組名表示的是整個(gè)數(shù)組所占的字節(jié)數(shù)。在這里數(shù)組指針的類型是。這也是我們可以用數(shù)組指針來接收二維數(shù)組數(shù)組名的原因。 目錄 零.前言 一.指針的定義 二.指針類型的意義 1.指針類型決定了指針解引用時(shí)一次訪問幾個(gè)字...
閱讀 1778·2023-04-25 23:43
閱讀 962·2021-11-24 09:39
閱讀 744·2021-11-22 15:25
閱讀 1744·2021-11-22 12:08
閱讀 1118·2021-11-18 10:07
閱讀 2104·2021-09-23 11:22
閱讀 3375·2021-09-22 15:23
閱讀 2608·2021-09-13 10:32