2D арифметика указателя в C - PullRequest
1 голос
/ 19 июня 2011

Я пытаюсь поменять местами 2 элемента в двумерном массиве на C. Безуспешно.

Спасибо за ответы, но я отредактировал этот код, чтобы прояснить, что я делаю.

typedef struct smystruct { /* stuff... */ } mystruct;

void nswap( mystruct ** a, mystruct ** b )
{
  mystruct * tmp = *a;
  *a = *b;
  *b = tmp;
}

void nqsort( mystruct ** h, int m, int n )
{
  double key = 0.0;
  int i = 0, j = 0, k = 0;

  if( m < n ) {
    // choose the pivot point...
    k = (m + n) / 2;

    nswap( &h[ n ], &h[ k ] );

    key = (*h+m)->prob;

    i = m + 1;
    j = n;

    while ( i <= j ) {
      while ( (i <= n) && (*h+i)->prob <= key )
        i++;
      while ( (j >= m) && (*h+j)->prob > key )
        j--;
      if ( i < j ) {
        nswap( &h[i], &h[j] );
      }
    }

    // swap two elements
    nswap( &h[m], &h[j] );

    // recursively sort the lesser list
    nqsort( h, m, j-1 );
    nqsort( h, j+1, n );
  }
}

int main()
{
  mystruct * p = NULL;

  // get the number of nodes (m)...
  fscanf( in, "%d", &m );

  // allocate memory for the node and connectivity matrix arrays...
  p = (mystruct*)malloc( sizeof( mystruct ) * m );

  // read in the location and associated probabilities!...
  for ( ; loop < m ; ++loop ) {
    mystruct * tmpnode = p + loop;
    tmpnode->str = (char*)malloc( sizeof( char ) * 1024 );
    fscanf( in, "%s %lf", (char *)tmpnode->str, &tmpnode->prob );
  }

  nqsort( &p, 0, m );
}

Излишне говорить, что это не работает.Я искал примеры, и ничего не работает.Буду признателен за n00b.

Ответы [ 3 ]

2 голосов
/ 19 июня 2011

Несколько вещей не так.

1 / Ваш двумерный массив выделен неправильно (или отсутствует код). 2 / Правильный способ сделать такое 2D-распределение - использовать указатель Iliffe (как рекомендовано в Numrical Recipes на C / C ++).

mystruct** alloc_array( int h, int w )
{
  int i;
  mystruct** m = malloc(h*sizeof(mystruct*));
  m[0] = malloc(h*w*sizeof(mystruct));
  for(i=1;i<h;i++) m[i] = m[i-1]+w;
  return m;
}

void release_array(mystruct** m)
{
  free( m[0] );
  free( m);
}

Этот способ выделения дает вам как непрерывный блок памяти (который легче обрабатывать, более дружественный к кешу, не требует каких-либо вычислений индекса), так и доступ [] [].

Ваша функция свопинга становится:

void swap( mystruct* a, mystruct* b )
{
  mystruct tmp = *a
  *a = *b;
  *b = tmp;
}

и может называться как:

swap( &some_tab[i][j], &some_other_tab[u][v] );

В полном примере:

int main()
{
  mystruct** my_array = alloc_array(3,4); /* 3x4 mystruct array */

  /* fill the array */

  /* Swap some */

  swap( &my_array[2][1], &my_array[0][3] );


  release_array(my_array);
}
2 голосов
/ 19 июня 2011
  1. Последний элемент имеет индекс count-1, а не count.

    h[0]  h[1]  h[2]  h[3]  h[4]  h[5]  h[6]  h[7]  h[8]  h[9]
    ----------------------------------------------------------
                         total 10 elements
    
  2. Я не знаю, что такое fwnodes, возможноВы имеете в виду h.

0 голосов
/ 19 июня 2011

Вы передаете указатель на массив в вашу функцию.Это означает, что h имеет только один элемент.

swap( &p, 10 );

Должно быть:

swap( p, 10 );

Это означает, что вам нужно изменить свою функцию, чтобы принимать массивы mystruct или изменить p к массиву указателей на mystruct.

И, как предположил Кенни, последний элемент имеет индекс 9, а не 10.

...