2012-12-22 32 views
2

我想寫一個函數,它帶有兩個參數:一個void指針類型到任意內存塊和一個塊bytesize。知道塊中寫入的數據的結構類型,函數應該打印包含的值。類型轉換最後一次? (C)

然而,首先,我建議的代碼沒有工作:

#define RECORD struct record 
struct record { 
     char nam[32]; 
     double val; 
}; 

void xprint (void *p, long j) 
{ 
    j /= sizeof(RECORD); 
    RECORD r; 

    while(j--){ 
     r = *((RECORD *)p++); 
     printf("\n..%s.., ..%lf..\n",r.nam, r.val); 
    } 
    return; 
} 

所以,我想出了一些交替,主要是在代碼的一部分遞增:

void print (void *p, long j) 
{ 
    j /= sizeof(RECORD); 
    RECORD r = *((RECORD *)p); 

    while(j--){ 
     printf("\n%s,\t%8.2lf\n",r.nam, r.val); 
     r = *(++(RECORD *)p); 
    } 
    return; 
} 

現在它完成了這項工作,但代碼看起來不那麼緊湊。

經過一番檢查,我發現問題出在r = *((RECORD *)p++);一行。看來,當涉及到後綴增量時,p不再被類型化,因此p僅增加一個字節。

是否可以重寫xprint函數,以便我仍然可以使用後綴操作符,但應用於類型指針?

+1

? – cmc

+0

我剛剛插入了RECORD const的#define becuse。我用stuct _name {};而不是typedef struct {} _name;因爲否則我會得到'''未知'錯誤的存儲。 – brnady

+0

'p ++'必須是你的編譯器的擴展,標準C不允許增加'void *',它有很好的理由。編譯你的代碼的選項,強制對標準進行更嚴格的解釋,例如對於gcc,這將是'-std = c99'。 –

回答

3

立即將void *轉換爲RECORD *,然後將該指針用於該函數的其餘部分。

void print (const void *p, size_t size) 
{ 
    const RECORD *r = p; 
    size_t count = size/sizeof(*r); 

    while (count--) { 
     printf("\n%s,\t%8.2lf\n", r->nam, r->val); 
     ++r; 
    } 
} 

我也在這裏做了一些文體上的改變,比如更好的變量名和添加const


在附註中,正如Clement Rey所說,使用typedef比定義更好。

typedef struct record record_t; 

你甚至可以結合使用結構定義的類型定義:你爲什麼要使用一個定義一個typedef,而不是同時宣告你的結構

typedef struct { 
    char nam[32]; 
    double val; 
} record_t; 
+0

謝謝,快速回答......它一定會有所幫助!但是,我是否正確解釋了類型轉換的行爲? – brnady

+1

@ user1815319(RECORD \ *)p ++)將p轉換爲RECORD *,您可以將其轉換爲產生臨時值(儘管您看不到這一點)。 p ++遞增p,而p仍然是一個void *(畢竟,它被聲明爲void * p。) – nos