簡體   English   中英

在ANSI C中使用指針替換字符

[英]Replacing a character using pointer in ANSI C

我正在使用gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3的ubuntu 12.04lts。 我可以在第一個程序中替換字符,但是即使編譯成功也不能在第二個程序中得到輸出? 我遇到細分錯誤。 誰能解釋原因?

  #include<stdio.h>
  int main(void)
  {
  char word[] = "Bhilip";
  char *cp = word ;
  puts(word);
  cp[1] = 'T';  // allowed??
  puts(word);
  return 0;
  }



  #include<stdio.h>
  int main(void)
  {
    char * p1 = "Bhilip";
    p1[0] = 'T';    //allowed?
    printf("\nThilip");
    printf(" %s \n\n", "Thilip");
    return 0 ;
  }
char * p1 = "Bhilip";

聲明一個指向字符串文字的指針。 它可能保存在只讀存儲器中,因此無法修改。

p1[0] = 'T';

嘗試修改字符串文字中的第一個字符。 這導致不確定的行為,可能包括段錯誤。

如果您想要一個可寫的字符串,則可以聲明一個堆棧緩沖區,並使用字符串文字對其進行初始化。

char p1[] = "Bhilip";
p1[0] = 'T'; // now allowed

根據ISO C11 6.4.5 String literals /6 (盡管此行為在標准的較早版本中已經存在了一段時間):

如果它們的元素具有適當的值,則不確定這些數組是否不同。 如果程序嘗試修改這樣的數組,則行為是不確定的。

這意味着如果您希望行為得到良好的定義,則不允許修改字符串文字的內容。 可能適用於某些實現,但絕不能保證。 在某些實現中,字符串文字被放置在標記為只讀的內存中,因此嘗試對其進行修改會引發錯誤。 在其他系統(例如嵌入式系統)中,可以將其放置在實際的只讀存儲器(ROM)中,這樣即使它沒有故障,該存儲器也不會更改。

其背后的一個可能原因是,它使編譯器能夠將字符串文字折疊在一起以提高效率。 例如,如果您的代碼具有definedundefined的兩個字符串,則它們可能以下列形式存在於內存中:

        +---+---+---+---+---+---+---+---+---+----+
0x1234: | u | n | d | e | f | i | n | e | d | \0 |
        +---+---+---+---+---+---+---+---+---+----+

地址undefined0x1234 ,地址defined0x1236

之所以說工作:

char word[] = "Bhilip";

是因為它創建法律上可修改的,有效字符數組:

  • 創建可修改的數組; 然后
  • 將單個字符復制到其中。

換句話說,它在功能上等同於:

char word[7];             // modifiable
strcpy (word, "Bhilip");  // initialise

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM