[英]C language pointers and arrays
#include <stdio.h>
int main()
{
char c[]="PRODUCTION 2019";
char *p=c;
printf("%s",p+p[3]-p[5]);
return 0;
}
我不明白 output 如何是RODUCTION 2019 。 有人可以詳細解釋一下嗎?
因為p[3]
是'D'
而p[5]
是'C'
那么p[3]-p[5]
是1
並且整個表達式p+p[3]-p[5]
就是p + 1
p[3]
和p[5]
分別是字母D
和C
。 即使不知道它們的實際 ASCII 代碼,這些代碼的差異也是1
,因此結果是
printf("%s",p+1);
編輯:代碼是 67 和 68,所以詳細形式是p+68-67
。
printf("%s",p+p[3]-p[5] );
如下進行
p+'D'-'C' = p+1
如果 p 指向字符串的開頭,即 P 處,則指針 p+1 指向“R”,這就是打印從 R 開始的字符串的原因。
p[3] 是數組中的第 4 個元素,p[5] 是第 6 個元素。
在這種情況下,第 4 和第 6 個元素分別是 D 和 C,它們的差:'D' - 'C' 等於 1。
因此,您的 printf 語句等效於:
printf("%s", p + 1);
它打印從第二個字符開始的字符串。
當你寫
printf("%s",p+p[3]-p[5]);
你在玩火。 您的代碼沒有崩潰只是為了運氣。
讓我們嘗試列出一些事實:
%s
用於打印字符串。 此格式需要一個字符串 (char *)。printf("%s",p);
將正確打印"PRODUCTION 2019"
。 因為p
是一個指向完整字符串的 char * 變量。p[3]
和p[5]
不是字符串。 它們是字符; 更准確地說, "PRODUCTION 2019"
的第四個和第五個字符:分別是“D”和“C”。 但它們也是字節整數,其值分別為 0x44 和 0x43。p+p[3]-p[5]
實際上是一個字符串:它是帶有一些偏移量的p
。 什么抵消? 0x44 ('D') - 0x43 ('C') = 1。由於這些原因,您的 printf 相當於
printf("%s",p+1);
所以如果它從第二個字符(p[1] 或p+1 )開始打印 p 指向的字符串是正確的。
但它實際上是在玩火! 如果p[n]-p[m]
會導致負偏移怎么辦? 這將導致嘗試在 p 開始之前打印字符,因此會出現未定義的行為。 如果p[n]-p[m]
(例如 'Z'-'A')大到超出給定的字符串長度,也會發生同樣的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.