2011-11-09 114 views
-3

我學習C++,我繼「思考在C++」的書,我做的練習,我不明白爲什麼在這個練習中:在C++中鍛鍊思維

的定義數組int。以該陣列的起始地址並使用static_cast將其轉換爲void*。編寫一個將void*,一個數字(表示多個字節)和一個值(表示每個字節應該設置的值)作爲參數的函數。該函數應該將指定範圍內的每個字節設置爲指定的值。嘗試使用int陣列上的功能。

此解決方案有效

#include<iostream> 

using namespace std; 

#define PR(EX) cout << #EX << ": " << EX << endl; 

void f1(void* v, size_t num_bytes, int val){ 

    unsigned char* p_addr = reinterpret_cast<unsigned char*>(v); 
    unsigned char byte = static_cast<unsigned char>(val); 

    for(size_t i = 0; i < num_bytes; i++){ 
    *p_addr = byte++; 
    p_addr++; 
    } 

    PR(num_bytes); 

} 

int main(){ 

    int a[5] = { 0, 0, 0, 0, 0 }; 
    int value = 67; 
    void* vp = static_cast<void*>(&a);  

    f1(vp, sizeof(a), value); 

    unsigned char* byte = reinterpret_cast<unsigned char*>(vp); 


    for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++){ 
    cout << "a[" << i << "] = "; 
    for(int j = 0; j < sizeof(int); j++){ 
     cout << reinterpret_cast<int*>(*byte) << " "; 
     byte++; 
    } 
    cout << endl; 
    } 

    return 0; 

} 

,而這其中並不

#include<iostream> 

using namespace std; 

#define PR(EX) cout << #EX << ": " << EX << endl; 

void f1(void* v, size_t num_bytes, int val){ 

    unsigned char* p_addr = reinterpret_cast<unsigned char*>(v); 
    unsigned char byte = static_cast<unsigned char>(val); 

    for(size_t i = 0; i < num_bytes; i++){ 
    *p_addr = byte++; 
    p_addr++; 
    } 

    PR(num_bytes); 

} 

int main(){ 

    int a[5] = { 0, 0, 0, 0, 0 }; 
    int value = 67; 
    void* vp = static_cast<void*>(&a); 
    unsigned char* byte = reinterpret_cast<unsigned char*>(vp); 

    for(size_t i = 0; i < (sizeof(a)/sizeof(a[0])); i++){ 
    cout << "a[" << i << "] = "; 
    for(size_t j = 0; j < sizeof(int); j++){ 
     cout << *byte; 
     byte++; 
    } 
    cout << endl; 
    } 

    PR(*byte); 


    f1(vp, sizeof(a), value);  

    for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++){ 
    cout << "a[" << i << "] = "; 
    for(int j = 0; j < sizeof(int); j++){ 
     cout << reinterpret_cast<int*>(*byte) << " "; 
     byte++; 
    } 
    cout << endl; 
    } 

    return 0; 

} 

的差別是在我定義指針byte,在「工作」的版本,它的功能是前在之前的「不工作」版本中調用。這兩個版本的cout

a[0] = 
a[1] = 
a[2] = 
a[3] = 
a[4] = 
*byte: 
num_bytes: 20 
a[0] = 0 0 0 0 
a[1] = 0x3b 0x8 0x40 0 
a[2] = 0 0 0 0 
a[3] = 0x4 0 0 0 
a[4] = 0 0 0 0 

num_bytes: 20 
a[0] = 0x43 0x44 0x45 0x46 
a[1] = 0x47 0x48 0x49 0x4a 
a[2] = 0x4b 0x4c 0x4d 0x4e 
a[3] = 0x4f 0x50 0x51 0x52 
a[4] = 0x53 0x54 0x55 0x56 
在第二個我東西,字節中以正確的方式改變

,而在第一個,在我看來那東西是怎麼回事錯誤。顯然,問題出在我定義指針的地方,因爲我是初學者,自己學習,所以我希望理解我在想什麼錯。

好吧,我明白我的錯誤感謝您的建議,我已經修改了代碼,現在它打印我所期待的

#include<iostream> 

using namespace std; 

#define PR(EX) cout << #EX << ": " << EX << endl; 

void f1(void* v, size_t num_bytes, int val){ 

    unsigned char* p_addr = reinterpret_cast<unsigned char*>(v); 
    unsigned char byte = static_cast<unsigned char>(val); 

    for(size_t i = 0; i < num_bytes; i++){ 
    *p_addr = byte++; 
    p_addr++; 
    } 

    PR(num_bytes); 

} 

int main(){ 

    int a[5] = { 0, 0, 0, 0, 0 }; 
    int value = 67; 
    void* vp = static_cast<void*>(a); 
    unsigned char* byte = reinterpret_cast<unsigned char*>(vp); 

    for(size_t i = 0; i < (sizeof(a)/sizeof(a[0])); i++){ 
    cout << "a[" << i << "] = "; 
    for(size_t j = 0; j < sizeof(int); j++){ 
     cout << reinterpret_cast<int*>(*byte); 
     byte++; 
    } 
    cout << endl; 
    } 

    byte = reinterpret_cast<unsigned char*>(vp); 

    f1(vp, sizeof(a), value); 

    for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++){ 
    cout << "a[" << i << "] = "; 
    for(int j = 0; j < sizeof(int); j++){ 
     cout << *byte << " "; 
     byte++; 
    } 
    cout << endl; 
    } 

    return 0; 

} 

a[0] = 0000 
a[1] = 0000 
a[2] = 0000 
a[3] = 0000 
a[4] = 0000 
num_bytes: 20 
a[0] = C D E F 
a[1] = G H I J 
a[2] = K L M N 
a[3] = O P Q R 
a[4] = S T U V 
+6

指出差異。另外,「不工作」是什麼意思?怎麼了? –

+3

你真的期望我們將這兩個程序逐行比較嗎?而且,是的,當你說「它不行」時它意味着什麼? – sbi

+0

沒有一個程序按照規範工作:你在循環中每次迭代增加'byte',而規範說明每個字節應該被設置爲相同的值。 –

回答

0

您正在使用一個指針來打印數組的價值觀和打印循環提前指針。 在您的第二個代碼列表中,您無法將指針重置爲數組的開頭。你的第二個循環打印的值超過了數組的末尾。

編輯:

在您打印*byte這被解釋爲一個8位字符值,你的第一個循環。該數組被初始化爲所有不是可打印的ASCII值的零。如果要打印數字值,請將*byte更改爲static_cast<int>(*byte)

在您的第二個循環中,您的reinterpret_cast<int*>(*byte)嘗試將unsigned char重新解釋爲指向int的指針。我不認爲這就是你的意思。您應該像第一個循環那樣將其更改爲static_cast<int>(*byte)。或者,因爲你的函數用有效的ASCII字符代碼填充了數組,所以第二個循環可以發送*byte給cout。

我對你的代碼的變化和輸出可以看出here

+0

@ drkg4b,更新了答案。 – Blastfurnace

+0

謝謝,我認爲我們在同一時間獲得解決方案,我發佈了更正的代碼,感謝您的幫助和建議! – drkg4b