簡體   English   中英

我不了解C字符串

[英]Something I don't get about C strings

有關C字符串的幾個問題:

  1. char*char[]都是指針嗎?
  2. 我已經了解了指針,並且可以說char*是一個指針,但是為什么它會自動成為一個字符串,而不僅僅是指向1個char的char指針? 為什么可以容納琴弦?
  3. 為什么與其他指針不同,當您向char*指針分配新值時,實際上是在內存中分配新空間來存儲新值,而與其他指針不同,您只是替換了指針所指向的內存地址中存儲的值在?

指針不是字符串。
字符串是具有array of char類型array of char常量對象,並且具有以下性質:該數組的最后一個元素為空字符'\\0' ,而該字符又是具有以下內容的int值(轉換為char類型)整數值0

  1. char*是指針,而char[]不是。 char[]類型不是“真實”類型,而是不完整的類型 指定C語言的方式是,在定義具有char類型數組的具體變量(對象)時,可以通過某種方式很好地確定數組的大小。 因此,沒有變量具有char[]類型,因為這不是類型(對於給定對象)。

    但是,具有array of N objects of type char類型array of N objects of type char每個對象都會自動提升為char * ,即, 指向char指針指向該數組的初始對象。

    另一方面,這種促銷並不總是進行的。 例如,運算符sizeof()將為char*提供的結果與為an array of N chars提供的結果不同。 在前一種情況下,給出了pointer to charpointer to char的大小(通常每個指針的大小相同...),在后一種情況下,給出了值N ,即數組的大小。

    當將函數參數聲明為char*char[]時,行為是不同的。 由於該函數無法知道數組的大小,因此可以將兩個聲明都視為等效。

  2. 實際上,您就在這里: char *是僅指向1個字符對象的指針。 但是,它可以用來訪問字符串,正如我現在將向您解釋的那樣:在第1段中,我向您展示了字符串被認為是內存中具有array of N chars類型array of N chars對於某些N 這個值N足夠大以允許結尾的空字符(因為所有“字符串”都應位於C中 )。

    那么,這是怎么回事?

    理解這個問題的關鍵是對象(在內存中)的概念。
    當您有一個字符串,或更普遍地說,是一個char數組時 ,這意味着您已經找到了某種將數組對象保存在內存中的方法。
    該對象確定可以安全訪問的RAM內存部分,因為C已為其分配了足夠的內存。
    因此,當您使用char*變量指向該對象的第一個字節時,實際上可以確保訪問該內存位置“右側”的所有相鄰元素,因為C很好地定義了這些位置具有字節上面的數組。

    簡而言之:可以訪問由char*變量指向的字節的相鄰(右)字節,它們是有效的訪問位置,因此可以“迭代”指針以遍歷這些字節,直到指針的末尾為止。字符串,沒有“風險”,因為數組中的所有字節都是內存中連續的定義良好的位置。

  3. 這是一個復雜的問題,但它表明您不了解C中的指針,數組和字符串文字之間的關系。

    • 指針只是指向內存中某個位置的變量。
    • 指向char的pòinter指向僅一個具有char類型的對象。
    • 如果指針位置的相鄰字節對應於一個char數組,則指針可以訪問它們,因此指針可以“遍歷”數組對象占用的內存字節。
    • 字符串文字被視為char對象的數組,它隱式添加一個值為0(空字符)的結束字節。

    在任何情況下, T對象的數組都具有定義明確的“大小”。
    字符串文字有一個附加屬性:它是一個常量對象。
    嘗試適應並收集這些概念,以了解正在發生的事情。

    並請我澄清。

其他說明:

考慮以下代碼:

#include <stdio.h>
int main(void)
{
   char *s1  = "not modifiable";
   char s2[] = "modifiable";
   printf("%s ---- %s\n\n", s1, s2);
   printf("Size of array s2: %d\n\n", (int)sizeof(s2));

   s2[1] = '0', s2[3] = s2[5] = '1', s2[4] = '7',
   s2[6] = '4', s2[7] = '8', s2[9] = '3';
   printf("New value of s2: %s\n\n",s2);
   //s1[0] = 'X';   // Attempting to modify s1
}

s1的定義和初始化中,我們使用字符串文字"not modifiable" ,該字符串具有恆定的內容和恆定的地址。 它的地址作為初始化分配給指針s1
任何嘗試修改字符串字節的操作都會產生某種錯誤,因為數組內容是只讀的。

s2的定義和初始化中,我們有字符串文字"modifiable""modifiable"具有恆定的內容和恆定的地址。 但是,現在發生的是,作為初始化的一部分,字符串的內容被復制到char s2的數組中。 未指定數組s2的大小(聲明char s2[]提供了不完整的類型),但是在初始化之后,已確定數組的大小,並將其定義為已復制字符串的確切大小(加上1個用於保存字符串的字符) 字符或字符串結尾標記)。

因此,字符串文字"modifiable"用於初始化可修改數組s2的字節。
正確的方法是在此時更改字符。
為了更方便地修改和分配字符串,必須使用標准標頭<string.h>

  1. char *s是一個指針, char s[]是一個字符數組。 防爆。

     char *s = "hello"; char c[] = "world"; s = c; //Legal c = address of some other string //Illegal 
  2. char *s不是字符串; 它指向一個地址。 防爆

     char c[] = "hello"; char *s = &c[3]; 
  3. 分配指針不會創建內存; 你指的是記憶。 防爆。

     char *s = "hello"; 

    在此示例中,當您鍵入“ hello”時,您正在創建特殊的內存來保存字符串“ hello”,但這與指針無關,指針僅指向該位置。

暫無
暫無

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

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