2013-07-13 38 views
-2

在我的代碼中,我只是使用格式字符串打印相同的對象。但是,結果並不相同。根據我的見解,我認爲結果應該是97 97 97,但結果是97 98 99使用格式字符串的打印類

輸出發生了什麼?我實際上並不瞭解發生了什麼。你能解釋一下嗎?

class A { 
public: 
    int a, b, c; 
    A() { 
     this->a = 97; 
     this->b = 98; 
     this->c = 99; 
    }; 
}; 

int main(int argc, char **argv) { 
    A a; 
    printf("%d %d %d\n", a, a, a); 
    return 0; 
} 
+3

C#,C++和C是不同的語言。對於C++,使用%d打印類對象是未定義的行爲。由於缺乏對該主題的最低限度知識,投票結束。 –

+3

這張海報顯然是一個初學者,所以我不建議關閉,而應該指出錯誤和錯誤,應該做些什麼以及在哪裏獲得啓發性信息......(PS:它傲慢的精英主義想要結束總結) – slashmais

+2

我認爲OP *已經展示了至少最少的知識,並努力解釋期望和實際結果以及最少的編譯代碼示例。這個問題唯一的問題是不恰當的標籤,它已被糾正。 –

回答

7

aA類型的對象,而不是一個整數,這是什麼%d需要。這導致了未定義的行爲,這意味着任何事情都會發生。在這種情況下,似乎發生的情況是格式字符串之後的a s之一佔用堆棧上的三個參數將佔用的相同位置,因此其數據成員(a,bc)是什麼三個%d最終使用。

打印存儲在A::a三倍值97,你應該這樣做:

printf("%d %d %d\n", a.a, a.a, a.a); 
+0

很好的答案,他們除了你沒有(可能無法)解釋爲什麼該程序打印97 98 99.該問題與cpp無關。這與堆棧內存結構有關。我自己解決了這個問題。但這個答案是非常封閉的解決方案。謝謝。 –

+0

@crazy_rudy:謝謝你的勾號。但我不明白你的意見;我參照堆棧解釋了爲什麼你可能會得到你所看到的輸出。 –

+0

是的,你做到了。我的意思是,除了你之外,每個回答者都無法解釋原因。 –

1

你的代碼的小改寫:

class A 
{ 
public: 
    int a; 
    int b; 
    int c; 
    A(){ 
     a = 97; 
     b = 98; 
     c = 99; 
    } 
void AFunction(int a, int b, int c){ 
     this->a = a; 
     this->b = b; 
     this->c = c; 
    } 
}; 
int main(int argc, char **argv){ 
    A a; 
    printf("(Expect: 97 97 97) %d %d %d\n", a.a, a.a, a.a); 
    printf("(Expect: 97 98 99) %d %d %d\n", a.a, a.b, a.c); 

    a.AFunction(1,2,3); 
    printf("(Expect: 1 2 3) %d %d %d\n", a.a, a.b, a.c); 

    return 0; 
} 

使用this->語法構造不錯,只是不必要的。在示例AFunction()中,有必要使用this->,以便編譯器可以確定您所指的是哪個a, bc

請參閱Marcelo的回答,瞭解您的代碼錯誤的原因。

好(!和免費dowloadable)本書是Thinking in C++ by Bruce Eckel

1

我剛剛清理你的代碼有點看起來更像C++:

class A { 
public: 
    // google for "constructor initialization list" 
    A(): a_(97), b_(98), c_(99) 
    {} 

    void print() const { 
     // any member variable reference "a" implies "this->a" 
     printf("%d %d %d\n", a_, b_, c_); 
    } 

// Having public member variables in a class is rarely a good idea 
private: 
    int a_; 
    int b_; 
    int c_; 

    // In C++11 you can specify default values for the members like this: 
    // 
    // int a_ = 97; 
    // int b_ = 98; 
    // int c_ = 99; 
    // 
    // Then you can omit the constructor definition. 
}; 

int main(int argc, char **argv){ 
    A a; 
    a.print(); 
    return 0; 
}