⭐部落格首頁:️CS semi首頁
⭐歡迎關注:點贊收藏+留言
⭐系列專欄:C語言初階
⭐代碼倉庫:C Advanced
家人們更新不易,你們的點贊和關注對我而言十分重要,友友們麻煩多多點贊+關注,你們的支援是我創作最大的動力,歡迎友友們私信提問,家人們不要忘記點贊收藏+關注哦!!!
文章目錄
- 前言
- 一、簡介
-
- 1.認識strcpy
- 2.應用strcpy
- 3.監視分析
- 二、模拟實作strcpy
-
- 1.初步實作
- 2.輸入空指針
- 3.assert
- 4.這階段完整代碼
- 三、傳回值
-
- 1.傳回類型
- 2.const
- 四、完整代碼
- 總結
前言
strcpy函數其實大家并不陌生,但是每次用的時候要麼就複制到字元串的地方不對,要麼就出現錯誤,那到底該怎麼用這個函數呢?接下來我将詳細給大家講解strcpy這個函數的本質和用法!
一、簡介
1.認識strcpy
再認識這個函數之前,我先放一張圖檔供大家了解一下:
在MSDN中查一下這個函數,發現是從後面的數組複制一份複制到前面的數組,那當然,大家夥可能會問了,為什麼有一個const被圈出來了,這個const很熟悉呀,之前見到過了,大家夥繼續往後看,在文中我會跟大家詳細解說一下這個const與指針配套起來的用法。
2.應用strcpy
先帶大家看一看運用一下strcpy的奇效。
#include<stdio.h>
#include<string.h>
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
看,運用了這個函數以後感覺是在是太友善了,能把arr2中的“hello\0”全部複制到arr1[20]裡面去,唉,大家可能會問了,螢幕上顯示的是hello啊,沒有那個’\0’,大家繼續往下面看,就立馬能夠了解了。
3.監視分析
先上幾張圖檔讓大家了解了解。
1.将*賦到arr1數組中。
2.将hello+’0’賦到arr2數組中。
3.進行複制的操作。
4.原理圖
利用螢幕看strcpy函數能夠看到它的本質就是将後面數組裡面的字元串+‘、0’拷貝到前面的數組中,但是為什麼會有\0呢,這個很簡單,arr[]={a,b,c,d}與arr[]="abc"是有本質的差別的,後者多一個\0,大家可以去看看我以後寫的關于數組的區分的部落格哦!
二、模拟實作strcpy
1.初步實作
先上個代碼:
代碼1:這個代碼很好了解,就先取數組的首位址并交換再往後加加,直到最後一個元素進行交換完退出循環。
#include<stdio.h>
//#include<string.h>
void my_strcpy(char* dest, char* src) {
while (*src != '\0'){
*dest++ = *src++;
}
*dest = *src; //拷貝\0
}
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
代碼2:這個代碼可以把\0直接列印出來,不需要最後一步加上交換一次\0。
#include<stdio.h>
//#include<string.h>
void my_strcpy(char* dest, char* src) {
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
但這代碼實作的看似沒什麼問題,可是也隐藏着一個很大的問題,數組是我已經定義好了的,但是,如果是在主函數裡面輸入NULL(空指針)呢?那讓我們先來看看。
2.輸入空指針
輸入空指針後,編譯器立馬就報錯了,是以,這是肯定不行的!那怎麼解決呢?接下來上一串代碼!
子函數裡加了先判斷輸入的兩個指針元素存不存在空指針,有空指針那就不進行後續操作。
#include<stdio.h>
//#include<string.h>
void my_strcpy(char* dest, char* src) {
if (src == NULL || dest == NULL)
{
return;
}
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char* p = NULL;
my_strcpy(arr1, p);
printf("%s\n", arr1);
return 0;
}
大家想一個問題,如果一個程式員喝了點小酒醉了,隻看到了這個程式可以直接運作,很開心的到老闆那裡邀功,老闆說,你這做的啥!為什麼導緻程式員犯錯了呢,很簡單,機器沒有報錯,程式員以為是對的,是以,接下來引進一個新的函數為“斷言’(assert)函數。
3.assert
assert中可以放一個表達式,表達式的結果如果為假,就報錯,如果為真那就正常運作
實作代碼:
#include<assert.h>
#include<stdio.h>
//#include<string.h>
void my_strcpy(char* dest, char* src) {
/*if (src == NULL || dest == NULL)
{
return;
}*/
assert(src != NULL);
assert(dest != NULL);
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char* p = NULL;
my_strcpy(arr1, p);
printf("%s\n", arr1);
return 0;
}
很明顯,這個程式報錯了,而且給你标注了哪裡出錯了,是不是很友善快捷,當然,頭檔案不要漏掉。
4.這階段完整代碼
這一階段的完整代碼如下:
#include<assert.h>
#include<stdio.h>
//#include<string.h>
void my_strcpy(char* dest, char* src)
{
assert(dest && src);//斷言指針的有效性
while (*dest++ = *src++)
{
;
}
}
int main()
{
//strcpy - 字元串拷貝
//char arr1[20] = "xxxxxxxxxxx";
//char arr2[] = "hello";
//my_strcpy(arr1, arr2);
//printf("%s\n", arr1);
char arr3[20] = {0};
char* p = NULL;
my_strcpy(arr3, p);
return 0;
}
三、傳回值
大家如果細心看那張strcpy的圖,會發現兩個小問題,這strcpy是有傳回值的呀,還有那個const怎麼一直沒有解決呢?接下來,我們開始解決問題!
1.傳回類型
那接下來修改一下這個代碼吧!
#include<assert.h>
#include<stdio.h>
//#include<string.h>
char* my_strcpy(char* dest, char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "*************";
char arr2[] = "hello";
printf("%s\n", my_strcpy(arr1, arr2)); //鍊式通路
return 0;
}
這樣就有傳回值了!
2.const
接下來到了最激動人心的時刻,久久困擾的const該怎麼做呢?下面且聽我分析。
大家先來看看這張圖檔,生動形象的解釋了const。
情況一:const 在的左邊:const int p 與 int const * p 一樣哦~
//const放在* 的左邊,const修飾的是指針指向的内容,表示指針指向的内容,不能通過指針來改變了; 但是指針變量本身可以修改
int num = 0;
int n = 1000;
const int* p = #
*p = 20;//err
p = &n;//ok
情況二:const 在*的右邊:int * const p
const放在*的右邊,const修飾的指針變量本身,表示指針變量本身的内容不能被修改,但是指針指向的内容,可以通過指針來改變。
int* const p = #
*p = 20;//ok
p = &n;//err
到這裡就完美解決了strcpy函數的問題。
四、完整代碼
#include<assert.h>
#include<stdio.h>
//#include<string.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "*************";
char arr2[] = "hello";
printf("%s\n", my_strcpy(arr1, arr2)); //鍊式通路
return 0;
}
總結
模拟strcpy函數讓我們大家深刻了解了這個函數的原理以及用法,最好的一點是讓我們了解了assert和const的使用,一舉三得!!!!
客官都閱讀到這邊了,碼字不易,求個三連支援!