2015-09-13 88 views
-1

我在嘗試理解toupper()函數時遇到了一個有趣的問題。請找到下面的代碼: 問題在這裏是在輸出我失蹤我的輸入字符串始終的第一個字符。關於toupper()使用指針運算

請糾正我的錯誤。我在發佈這篇文章之後對此做了太多的介紹。

void UpperString() 
{ 

    char arr [10]; 
    memset(arr, 0x00, sizeof(arr)); 
    strcpy(arr, "abcd"); 
    char *ptr = arr; 
    char *temp = ptr; 
    printf("Before Upper String - %s\n",ptr); 
    while(*ptr++ = toupper(*ptr)) 
    { 
     printf("ptr - %s\n",ptr); 
     printf("FULL - %s\n",temp); 
    } 
    printf("After Upper String - %s\n",temp); 
    return; 
} // UpperString() 

輸出

Before Upper String - abcd 
ptr - bcd 
FULL - Bbcd 
ptr - cd 
FULL - BCcd 
ptr - d 
FULL - BCDd 
After Upper String - BCD 
+1

我認爲你必須在'* PTR ++ = TOUPPER(* PTR)未定義的行爲':你從'ptr'讀取(在'* ptr',函數參數)並且你正在修改'ptr'(在'ptr ++'中),並且它們之間沒有序列點。 – melpomene

+0

這段代碼是C程序員之間的競爭對手,但是我保存的正常代碼保持良好的控制效果。太多的操作在同一個地方內聯 –

回答

0

您詢問了解TOUPPER(),但在你的代碼中的問題無關使用此功能。

while(*ptr++ 

*p++有感覺「值從ADDRES下班後&增量PTR」,如果第一NR 0),但PTR遞增

toupper(*ptr)) 右側從已經前進指針讀取信這樣用電池, 'b',讓 'b',並會在小區中設置a

這裏是沒有那樣的問題相同的代碼:

void UpperString() 
{ 

    char arr [10]; 
    memset(arr, 0x00, sizeof(arr)); 
    strcpy(arr, "abcd"); 
    char *ptr = arr; 
    char *temp = ptr; 
    printf("Before Upper String - %s\n",ptr); 
    while(*ptr = toupper(*ptr)) 
    { 
     printf("ptr - %s\n",ptr); 
     printf("FULL - %s\n",temp); 
     ptr++; 
    } 
    printf("After Upper String - %s\n",temp); 
    return; 
} 
+0

爲什麼會下降?告訴準確,如果你有收費 –

+0

你的英語很難理解,你給出的解釋是錯誤的:C不評估表達式從左到右。 – melpomene

+1

也許評估順序是可導入的(在編譯器之間),但是你如何描述交換a我b –

1
while(*ptr++ = toupper(*ptr)) 

此行有問題。您傾向於在單個執行行中多次更改ptr的值,因此會調用未定義的行爲

C99§6.5:「2。在前一個和下一個序列點之間,一個對象應該通過評估一個表達式最多修改其存儲值一次。此外,只讀取先前值以確定要存儲的值。「

在另一行中遞增。

while(*ptr= toupper(*ptr)){ 
// your code 
... 
ptr++; 

}

+0

嘿Amey,謝謝你的回覆。我明白了你的觀點,但相同的代碼在一個處理器中的工作方式與預期的相同,但在其他處理器中卻沒有。 – sakthi

+0

@sakthi你的意思是它在一個系統上工作,而不是在其他系統上工作?這可能是未定義行爲的副作用。在** UB **輸出可以是任何可能甚至我的電話號碼:) – ameyCU

0

在C中的規則是相同的變量應在一個單獨的操作僅一次修改,並且僅用於確定先前的值。參考:6.5 C99草案n1256中的表達式§2:在前一個和下一個序列點之間,一個對象的存儲值 最多可以通過評估表達式進行一次修改。而且,前值 應只讀,以確定該值存儲

在同一份聲明中,你改變的ptr的價值,而且在toupper(*ptr)使用它:這兩個操作不排序,你會得到未定義的行爲。

你應該寫:

while(*ptr = toupper(*ptr)) /* Ok ptr is unchanged, and *ptr is read to compute value to store */ 
{ 
    printf("ptr - %s\n",ptr); 
    printf("FULL - %s\n",temp); 
    ptr += 1; /* Ok ptr is changed here but not use elsewhere */ 
}