[英]Fundamental C pointer question using 'strcpy'
男人,指針繼續給我帶來麻煩。 我以為我理解了這個概念。(基本上,當你想操縱ptr指向的位置保存的實際內存時,你會使用* ptr。如果你想通過做這樣的事情來移動指針,你會使用ptr作為ptr ++或ptr--。)所以,如果是這種情況,如果你使用星號來操縱指針所指向的文件,這是如何工作的:
char *MallocAndCopy( char *line ) {
char *pointer;
if ( (pointer = malloc( strlen(line)+1 )) == NULL ) {
printf( "Out of memory!!! Goodbye!\n" );
exit( 0 );
}
strcpy( pointer, line );
return pointer;
}
malloc返回一個指針,所以我理解為什么if條件中的“指針”不使用星號。 但是,在strcpy函數中,它將行的CONTENTS發送到指針的CONTENTS。 不應該是:
strcpy( *pointer, *line);
????? 或者我對指針的理解是正確的,這只是strcpy函數的工作方式嗎?
C樣式字符串是字符字節數組。 當您將數組作為指向數組類型的指針傳遞時,指針包含數組的第一個元素的地址。
strcpy
函數將指針指向源數組的第一個char
(它是字符串的開頭)和指向目標數組中第一個char
的指針,並遍歷源,直到它達到'\\0'
字符,它終止了字符串。
這也是為什么當你調用malloc
,傳遞給它的大小是strlen(line)+1
,因為你需要為終止字符再分配一個字節(據我所知)。
char* strcpy(char *destination, const char *source)
是strcpy
的簽名。 它希望得到指針作為參數。 在您的實例中, pointer
已經是指針,因此是line
。
strcpy
將獲取指針source
和destination
,並復制從source
指向destination
的基礎字節,直到它遇到source
指向的字符串中的\\0
(NULL)字節,或者如果它因為從未遇到該字節而出現分段錯誤(未終止的字符串),只是讀入深淵。
如果您使用*pointer
,您實際上將取消引用指針並在指針指向的地址處獲取char
。
strcpy的簽名是
char * strcpy ( char * destination, const char * source );
您正在發送指向char *的指針,以及也是char *的行。 因此,您完全按預期匹配簽名。 發送*指針或*行將發送'這些指針指向的值' - 這將是錯誤的。
scrcpy接受一個指針,並將其指向的內容寫入另一個指針指向的位置 。 這就像重寫表格中的單元格內容一樣。 您不一定要剪切和粘貼表的一部分,您可以重寫其中的數字。 在這種情況下,指針只是提示您必須觸摸的單元格。
看一下strpcy()的聲明。
char *strcpy(
char *strDestination,
const char *strSource
);
你需要傳遞一個指針。 所以你不要取消引用指針和行 。 因為那會傳遞一個字符。
*
在strcpy
。
應用*
運算符稱為解除引用,與應用[0]
完全相同。
strlen
和strcpy
需要知道字符串的起始位置,以便它們可以訪問所有元素,而不僅僅是第一個元素。
pointer
的類型是char *
而*pointer
的類型是char
,表示沒有相鄰字符概念的單個字符。
通過編寫*pointer
,您可以獲得它指向的字符(恰好是pointer
代表的字符串的第一個字符)。 將其傳遞給strcpy
涉及創建該角色的副本。 除非你給它一個指向那個數據的指針,否則strcpy
不可能知道它應該寫在哪里。
以類似的方式,通過提供*line
你只給strcpy
一個字符串的第一個字符。
所以,你基本上是這樣說的:
我有兩個字符串。 我沒有把它們交給你。 一個的第一個字母是C,另一個的第一個字母是μ。 將第一個內容復制到第二個
我明白為什么你希望將*pointer
和*line
傳遞給strcpy
。 但請記住, pointer
指向內存中存儲內容的位置以及存在strlen(line)+1
的位置保留並分配了strlen(line)+1
字節的內存。 因此, strcpy
正在做的是從地址line
開始將strlen(line)
字節的內存復制到相應的位置,從pointer
的地址開始。 如果傳遞*pointer
和*line
, strcpy
將只能訪問第一個char
而不能訪問strlen(line)-1
的其余部分。 希望澄清你對指針的困惑以及為什么我們需要將指針傳遞給strcpy
。
您對strcpy
基本理解是正確的。 該函數確實將line
的內容復制到pointer
的內容上。 但是,您必須將指針傳遞給函數而不是數據本身。 這樣做有幾個原因。
首先,正在復制的數據是字符串(即數組)而不是常規變量。 將數組傳遞給函數時,不能將整個數組塞入單個函數參數中,因此必須將指針傳遞給數組的開頭。 這是C中傳遞數組的限制,並不特定於strcpy
。
此外,將數據傳遞給函數會為函數提供變量內容的副本 。 如果您直接將數據(或取消引用的指針)傳遞給strcpy
,則該函數將使用副本而不是原始數據。 它將無法將數據寫入原始字符串。
本質上,通過將指針移交給strcpy
您可以告訴它源數據和目標的位置。 該函數在內部處理所有的解引用。 在人類語言中,對strcpy
可以被認為是“從內存地址line
開始的字符串,並從內存地址pointer
開始寫一個副本”。 要傳遞內存地址,請使用指針。
將strcpy代碼視為:
char * strcpy(char * dst, char* src)
{
int i = 0 ;
for (;dst[i]=source[i++];);
return dst ;
}
\\ 0(NULL)是字符串和for循環的結尾。
你的功能基本上是strdup
功能。 該函數在許多平台上定義,如果不是,您可以這樣定義:
char * my_strdup(const char* s)
{
size_t len = strlen(s);
char *r = malloc(len+1);
return r ? memcpy(r, s, len+1) : NULL;
}
對於更長的字符串,memcpy通常比strcpy更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.