Сравнение методов обращения к массиву - PullRequest
0 голосов
/ 10 сентября 2010

Мне нужно распечатать матрицу 3 на 3 на C. Я мог бы придумать 3 различных способа сделать это. Все ли они одинаково оптимальны или один метод лучше другого?

Функция 1: Передача 2darray с использованием индексов массива

void printMatrix(int m[][3])
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t",m[i][j]);
  }
  printf("\n");
 }
}

Функция 2: Передача указателя dbl с использованием арифметики ptr

void printMatrix(int **m)
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t", *(*(m+i)+j) );
  }
  printf("\n");
 }
}

Функция 3: Передача указателя DBL с использованием арифметики ptr (снова)

void printMatrix(int **m)
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t",**m);
   (*m)++;
  }
  (*m)=(*m)-3;
  m++;
  printf("\n");
 }
}

Ответы [ 3 ]

2 голосов
/ 11 сентября 2010

Функция 1 работает с типом данных, отличным от функций 2 и 3.

Для функции 1 данные должны быть определены как int foo[3][3] или выделены как блок из 9 дюймов. С C89 вторая 3 должна быть константой времени компиляции, что может быть проблематично. Это можно обойти, передав простое int * и индексирование с использованием matrix[i * dim2 + j]. Если у вас есть C99, вы можете использовать массивы переменной длины и переменно измененные типы, чтобы сохранить хорошую нотацию matrix[i][j], но объявления могут быть немного более сложными и с некоторыми ограничениями.

Функции 2 и 3 работают с несколькими частями данных: массивом целочисленных указателей, которые указывают на дополнительные массивы целых чисел. Дополнительная косвенность может позволить некоторую простоту использования и гибкость (например, треугольную матрицу), но может снизить производительность.

Выбор между функцией 2 и функцией 3 для меня довольно ясен: используйте функцию 2. Следует избегать изменения структуры данных для операции, предназначенной только для чтения, если это возможно, даже если вы вернете ее так, как было : он предотвращает одновременное использование, и вы можете неправильно выполнить часть «положить его обратно», что затруднит диагностику проблем. Выражение *(*(m+i)+j) можно изменить на m[i][j], даже если оно делает что-то другое.

1 голос
/ 10 сентября 2010

Все они в значительной степени одно и то же внутри.Массивы по сути являются указателями со смещениями.Лично я думаю, что первое легче читать, поэтому я буду придерживаться этого.

0 голосов
/ 10 сентября 2010

Это не имеет значения!: -)

Действительно!Лучший способ - тот, который тебе нравится больше всего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...