[英]C style strings, Pointers, arrays
我無法理解C風格的字符串是什么。 新年快樂
我所知道的:指針包含一個內存地址。 取消引用指針將為您提供該內存位置的數據。
int x = 50;
int* ptr = &x; //pointer to an integer, holds memory address of x
cout << "&x: " << &x << endl; //these two lines give the same output as expected
cout << "ptr: " << ptr << endl;
cout << "*ptr: " << dec << (*ptr) << endl; //prints out decimal number 50
//added dec, so the program doesnt
//continue to printout hexidecimal numbers like it did for the
//the memory addresses above
cout << "&ptr: " << &ptr << endl; //shows that a pointer, like any variable,
//has its own memory address
現在我不明白(使用上面的內容作為我的困惑的來源):有多種方式來聲明字符串。 我正在學習C ++,但你也可以使用C風格的字符串(很好理解,雖然不如C ++字符串)
string intro = "Hello world!";
//the compiler will automatically add a null character, \0, so you don't have to
//worry about declaring an array and putting a line into it that is bigger than
//it can hold.
char version1[7] = {'H','i',' ','y','o','u','\0'};
char version2[] = "Hi you"; //using quotes, don't need null character? added for you?
char* version3 = "Hi you";
版本3是我遇到麻煩的地方。 這里有一個指向char的指針。 我知道數組名是指向數組中第一個元素的指針。
cout << " &version3: " << &version3 << endl; //prints out location of 'H'
cout << " *version3: " << *version3 << endl; //prints out 'H'
cout << " version3: " << version3 << endl; //prints out the whole string up to
//automatically inserted \0
之前,在“我所知道的”部分中,打印出指針的名稱會打印出它所持有的地址。 在這里,打印出指針的名稱會打印出整個字符串。 圍繞“嗨你”的雙引號會以某種方式告訴程序:“嘿,我知道你是一個指針,你被初始化為'H'的位置,但因為我看到這些雙引號,在內存位置向前跳過1個字節並打印出你看到的所有內容,直到達到\\ 0“(1字節移動,因為字符大1字節)。
如何打印出一個指針打印出一個字符串? 在打印出一個指針名稱之前,打印出它被初始化為的內存地址。
編輯: cout << &version3
是否打印出'H'的位置或指針的位置, version3
,其中包含內存地址'H'?
使用cout
打印char*
工作方式與打印不同,例如,帶有cout
的int*
。 為了與C風格的字符串兼容,帶有char*
參數的<<
的重載版本將char*
視為C風格的字符串。 如果要打印char*
所持有的內存地址,可以將其轉換為void*
。
是的,如果你寫任何一個
char *s1 = "hi lol";
char s2[] = "hi haha";
在字符串的末尾為您添加NUL( \\0
)終結符。 這兩者之間的區別在於s1
是指向字符串文字的指針,根據C標准,您不應該修改內容,而s2
是一個數組 ,即為您分配的內存塊堆棧, 初始化為保存值"hi haha"
,您可以隨意修改其內容。 為數組分配的內存量足以保存用作初始化程序的字符串,並自動為您確定,這就是方括號可以為空的原因。
一面注意:在C中,如果輸入char s[3] = "abc";
,然后s
將初始化為{'a', 'b', 'c'}
, 沒有 NUL終止符! 這是因為標准中的一個子句說如果數組中有空間 (或類似的措辭),則使用NUL終結符初始化此上下文中的字符串。 在C ++中,情況並非如此。 有關更多信息,請參閱初始化固定大小的char數組時沒有編譯器錯誤,但沒有足夠的空間用於null終止符 。
編輯,以回應您添加的問題:如果您有char *s = "..."
,並且你cout << &s;
,它將打印存儲指針 s
的地址,而不是s
保存的地址( s
引用的字符串的第一個元素的地址)。
我知道數組名是指向數組中第一個元素的指針。
不,不是。 它只會隱式轉換為一個(在大多數情況下)。
圍繞“嗨你”的雙引號會以某種方式告訴程序:“嘿,我知道你是一個指針,你被初始化為'H'的位置,但因為我看到這些雙引號,在內存位置向前跳過1個字節打印出你看到的一切,直到你達到\\ 0“?
不,他們沒有。 這是重要的類型。
std::ostream::operator<<
具有用於通用指針的過載( void *
) 和過載const char *
。 所以當你寫cout << "some char array or pointer";
,它將調用該重載,而不是其他指針類型的重載。 這種重載的行為有所不同:它不是打印指針的數值,而是打印出所有內容,直到NUL終止符。
你在這里問兩個問題,其中一個問題比較籠統,我將首先回答。
指針是指向內存中某個位置的“句柄”(稱為地址)。 該位置的內容是一個值。 如何解釋該值取決於指針的“類型”。 可以這樣想:地址是房子的位置,例如10 Main Street。 10 Main Street的內容是該地址的房子內容。 在C(和C ++)術語中:
int *p;
是一個可以保存整數地址的變量。
int x;
是一個整數的變量。
p = &x;
通過在p中存儲x的ADDRESS,p'指向'x。
x = 10;
在x中存儲值10。
*p == x
因為* p表示'使用p'的內容作為值,然后將其與x進行比較。
p == &x
因為&x表示'使用x的地址'作為值,然后將其與p進行比較,p是類型指針的變量。
字符串是零個或多個字符的序列,在C(和C ++)中用字符“和”表示。 在內存中,這些值是連續存儲的,並由一個尾隨的空字節自動終止,該字節是一個值為0的字節。字符串“Hello,world!” 假設您使用的是8位ASCII字符編碼,則存儲在內存中,如下所示:
65 101 108 108 111 44 32 87 111 114 108 33 0
您可以使用以下代碼段自行查看:
char *p = "Hello, World!";
int len = strlen(p);
int i;
for (i = 0; i <= len; ++i)
{
std::cout << std::dec << (int) p[i] << ' ';
}
std::cout << std::endl;
由於null(零字節)由編譯器自動添加到常量字符串,因此以下兩個數組的大小相同:
char a1[7] = { 'H', 'i', ' ', 'y', 'o', 'u', '\0' };
char a2[] = "Hi you";
std::cout << strcmp(a1, a2) << std::endl
簡單地說,'C樣式字符串'只是一個以null結尾的字符數組,它可以回答您的第一個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.