SORU
21 EYLÜL 2009, PAZARTESİ


"C" ilan eden bir dizi dönmek için işlev

Nasıl bir dizi döndüren bir işlevi yapabilir miyim? Bunu denedim

const int WIDTH=11;
const int HEIGHT=11;

int main() {
  char A[WIDTH][HEIGHT];
  A=rand_grid(WIDTH,HEIGHT);
  return 0;
}

// Initializes a random board.
char[][] rand_grid(int i, int k) {
  char* A[i][k];
  for(j=0;j<i;  j) {
    for(l=0;l<k;  l) {
      A[j][l]=ran(10);
    }
  }
  return A;
}

// Returns a random number from the set {0,...,9}.
int ran(int i) {
  srand((unsigned int) time(0));
  return(rand());
}

CEVAP
21 EYLÜL 2009, PAZARTESİ


Bazı şeyleri işaret etmek.

Öncelikle, buraya senin gibi bir dizi nesnesi atayın:

char A[WIDTH][HEIGHT];  
A=rand_grid(WIDTH,HEIGHT);

Dizi tür nesneler değil değiştirilebilir.

İkinci olarak, C fonksiyonlar return dizi türü olamaz. Dönüşişaretçilerdiziler için:

char (*foo(int width))[HEIGHT]
{
  /**
   * dynamically allocate memory for a widthxHEIGHT array of char
   */
  char (*newArr)[HEIGHT] = malloc(sizeof *newArr * width);
  /**
   * initialize array contents here
   */
  return newArr;
}

Sözdizimi biraz kafa karıştırıcı; olarak okur

       foo                                   -- foo
       foo(int width)                        -- is a function
                                             -- taking an int parameter
      *foo(int width)                        -- returning a pointer
     (*foo(int width))[HEIGHT]               -- to a HEIGHT-element array
char (*foo(int width))[HEIGHT]               -- of char

C89, YÜKSEKLİĞİ için yukarıdaki Pasajı derleme zamanı sabiti ayrılmaz bir ifade (bir makro, bir sayısal hazır bilgi, veya bir aritmetik ifade makrolar ve/veya oluşan sayısal harflerin) olmalıdır. Eğer o da C99 için doğru olup olmadığından emin değilim.

Ne yapmak istediğini ilan ettik parçacığı tabanlı, önceden tahsis ettiğin bir dizi alın ve içeriğini yapmaktır. En bağlamlarda, bir dizi türünü ifadesi örtülü olarak temel türü için bir işaretçi dönüştürülür unutmayın. İşlevi aslında aldığı bir işlev T N-elemanlı bir dizi başarılı olursa DÜŞÜK, T için bir işaretçi

void foo (T *p) {...}
...
T arr[N];
foo(arr);

2-B diziler için, biraz daha çirkin bir şey

void foo (T (*p)[M]) {...}
...
T arr[N][M];
foo(arr);

Bu da işlevin kullanışlılığını sınırlayan M derleme zamanında bilinen varlık, dayanır. İstediğin rasgele boyutu 2 boyutlu bir dizi ile başa çıkabilirim bir fonksiyonudur. En iyi yol bildiğim kadarıyla bunu yapmak için yerine geçen bir işaretçi dizisi, pass adresinin ilk elemanı dizi[1] ve geçiş satır ve sütun sayısı olarak ayrı parametreler:

void foo(T *base, size_t rows, size_t cols) {...}
...
T arr[N][M];
foo (&arr[0][0], N, M);

Rand_grid göreviniz bu gibi bir şey olacaktır:

void rand_grid(char *base, size_t rows, size_t cols)
{
  size_t i, j;
  for (i = 0; i < rows; i  )
  {
    for (j = 0; j < cols; j  )
    {
      /**
       * Since base is a simple char *, we must index it
       * as though it points to a 1-d array.  This works if
       * base points to the first element of a 2-d array,
       * since multi-dimensional arrays are contiguous.  
       */
      base[i*cols j] = initial_value();
    }
  }
}

int main(void)
{
  char A[WIDTH][HEIGHT];
  rand_grid(&A[0][0], WIDTH, HEIGHT);
  ...
}

< / ^ hr .

  1. İfadeler &A[0][0] A aynı değer (Bir taban adresi) verim rağmen, iki ifade de farklı. İlk ifade ikinci 2 boyutlu char dizi (char (*)[HEIGHT]) bir işaretçi olarak değerlendirir iken char (char *) için basit bir işaretçi olarak değerlendirir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:
C

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • jesiel santos

    jesiel santo

    15 Ocak 2009
  • NYCarspotter

    NYCarspotter

    26 EYLÜL 2011
  • tychoadragmire

    tychoadragmi

    20 Mart 2006