2011-11-29 45 views
7

不受約束的浮動陣列I由一個typedef浮法陣列,這樣的:的typedef用C

typedef float fooType[]; 

所以,我可以聲明和靜態初始化浮陣列是這樣的:

fooType myArray = {1.0, 2.0, 3.0} 

該工程精細。我可以說myArray[2]沒有問題,並且通常按照我的意願使用我的fooType。在我的程序的情況下這是非常清楚,fooType是一個數組類型(它實際上是一個巨大的查找表),這就是爲什麼我不是簡單地做typedef float fooType

我該如何聲明並使用變量指向bar並訪問bar的元素?我不能聲明這樣一個簡單的變量:

fooType bar = myArray; 

由於錯誤與invalid initializer;由於編譯器不知道要分配多少內存,我沒有想到它能夠工作。我試着用指針的幾件事情:

fooType *bar = myArray; 

這給出了一個警告:當我訪問的元素與bar[1]initialization from incompatible pointer type和錯誤。這個聲明很好,因爲我期望它,因爲現在類型匹配:

fooType *bar = &myArray; 

但是,如上所述編譯器錯誤與invalid use of array with unspecified bounds當我說bar[1]

這工作:

float *bar = myArray; 
float val = bar[3]; 

但我不希望因爲我失去了我的typedef的可讀性。

我一直埋藏在一個可愛OO世界(Java)的很長一段時間,所以我希望從這個理解用C在這種情況下什麼是習慣。如果沒有直接的解決方案,我已經準備好更改我使用typedef以適合約定。雖然我有一種感覺,但並不複雜。

感謝

+0

底線是你不**要爲數組進行typedef ...你可以,但是你會面對所有這些「麻煩」。例如這個東西'fooType myArray = {1.0,2.0,3.0}; fooType bar = myArray;'''float myArray [] = {1.0,2.0,3.0}; float bar [] = myArray;'它是否可讀? :)另一個「難題」是當你定義一個函數原型,它將'fooType'作爲_output_參數。 (類似於'memset'等) – debleek63

+0

現在很清楚@debleek63。謝謝。 –

回答

5

你在這裏遇到的問題是一個事實,即賦值運算符的右側使用時數組不是指針在C,而是衰減到指針的第一個元素。因此,如果聲明等

fooType myArray = {1.0, 2.0, 3.0} 

myArray類型是float[3],和& myArray的是(*float)[3],或「指針的3個浮標陣列」的陣列。因此,你不能簡單地說

fooType *bar = myArray; 

類型fooType*不是一個指向浮動......所以這實際上是不兼容的指針類型。這樣做

fooType* bar = &myArray; 

的工作,但您遇到的問題是,bar[1]不是陣列myArray中的元素,因爲bar本身就是一個指針。您需要解除引用bar,如(*bar)[1]才能訪問myArray中的元素。例如:

typedef float fooType[]; 
fooType myArray = {1.0, 2.0, 3.0} 
fooType* bar = &myArray; 
(*bar)[1] = 5.0; 

最後,請記住,使用C,你不能一個數組賦值給另一個數組...所以你can'd做這樣的事情:

fooType bar = myArray; 

這又回到了整個數組的問題及其衰變成指向第一個元素的指針,以及數組本身的類型與數組中第一個元素的類型不同的事實。

您可能最後只是想要typedef數組,然後鍵入數組元素類型,因爲使用float以便任何使用您的代碼的人都知道哪一種元素屬於另一種。

+0

謝謝傑森。現在有點清楚了。那麼我不能使用typedef,因爲它的類型是...'float []'?我應該使用'float * bar = myArray'嗎?不可讀,但它的工作原理。 –

+0

我知道編譯時數組的大小,所以你的第二個選項可以工作,但是這兩個建議都有很大的幫助。謝謝。 –

+0

順便說一句,我改變了我的答案一點點......似乎有一個語法錯誤阻止你從你的解決方案之一。 – Jason

1

您對Java C混合。

嘗試你的typedef改變

typedef float *fooType; 

可是後來你將不能夠初始化類型fooType的變量像

fooType myArray = {1.0, 2.0, 3.0}; 

因爲fooType是一個指針現在。

+0

隱藏'typedef'後面的指針類型通常被認爲是不好的做法... –

+0

@OliCharlesworth oops。謝謝。我只是想讓OP的代碼工作。 – Beginner

+0

感謝羅馬奧利。它的確如我寫的那樣工作:我可以初始化我的數組並直接使用它們。我需要能夠在問題中的聲明中進行初始化。然後我唯一不能做的就是聲明指向它們的其他變量。 –

0

使用Visual Studio 2013我發現你可以使用這個例子中的結構。這也似乎與Visual Studio的工作2015年

注意的是,使用malloc()創造fooType的陣列需要pfooType型而不是fooType*pfooType編譯類型的取消引用指針。我將typedeffloat更改爲doublesizeof(*p2)如預期從4更改爲8個字節。

#include <malloc.h> 

typedef float fooType[], *pfooType; 

int xxmain2(void) 
{ 
    fooType myArray = { 1.0, 2.0, 3.0 }; // define the array with its elements 
    pfooType p = myArray; // get a pointer to the array. 
    int i; 
    int nElements = sizeof(myArray)/sizeof(*p); // determine number of elements in the array. 

    pfooType p2 = malloc(sizeof(*p2) * 5); // malloc() an array of 5 elements. 

    for (i = 0; i < 5; i++) p2[i] = (float)i * 10.0; // initialize my malloced array. 
    myArray[0] = *p;  // dereference pointer 
    myArray[1] = p[1];  // use array subscripting with pointer 

    for (i = 0, p = myArray; i < nElements; i++) *p++ = 0; // increment the pointer to traverse the array. 

    free(p2); 
    return 0; 
} 

我還發現,我無法像fooType myRay2[10];(編譯錯誤「錯誤C2087:'myRay2:缺少標」)創建一個數組的指定大小或類似的東西。並且fooType myRay2;給出了「錯誤C2133:'myRay2':未知大小」的編譯錯誤。

所以唯一的辦法似乎是使用初始化來調整數組大小或使用malloc()創建一個特定大小的數組,然後需要free()