Как я могу сделать массив параметром функции в C ?

#c #encryption #hash

#c #шифрование #хэш

Вопрос:

У меня есть функция в программе, которую я пишу для школьной научной выставки, и что ей нужно сделать, это принять массив в качестве параметра, зашифровать значения массива и сохранить зашифрованные значения в строке. Как я могу это сделать?

Комментарии:

1. Как вы получаете массив? в vector , array просто массиве в стиле c или чем-то еще?

2. Какая часть вызывает у вас проблемы? Вы можете передать имя массива в качестве аргумента функции, которая принимает указатель на тип в качестве параметра; т.е. вы можете передать int a[10] в foo(int *p) . Конечно, foo() не будет знать размер a — вы должны передать это в качестве второго аргумента.

3. Возможно, я выразился недостаточно ясно. Каков правильный способ записи:

Ответ №1:

Есть несколько способов сделать это. Вот несколько примеров:

  • C-стиль

     void f(T *array, size_t size);
      

    В этом стиле массив распадается до указателя на первый аргумент, который передается функции в качестве первого аргумента. Поскольку при этом преобразовании теряется размер массива, вы также должны передать размер, что я делаю в качестве второго аргумента функции. Используйте это как:

     T  array[N]; //N is some compile-time constant.
    f(array, N);
      
  • C -стиль

     template<typename T, size_t size>
    void f(T (amp;array)[size]);
    
    void f(std::vector<T> amp; array);
      

    В этом стиле вы можете передать массив по ссылке, которая сохраняет размер массива, или вы можете использовать std::vector<T> вместо этого. Используйте это как:

     T array[N];
    f(array); //calls the first version (the template version)
    
    std::vector<T> v;
    //fill v
    f(v); //calls the vector version
      

    Добавлено @Mike: или вы можете использовать это, что еще лучше:

     template<typename FwdIterator>
    void f(FwdIterator begin, FwdIterator end)
    {
       for( ; begin != end ;   begin)
       {
            //your code
       }
    }
      

    Это лучше и более универсально, потому что с ним вы можете использовать стандартные контейнеры (такие как std::vector , std::list и т.д.), А также обычные массивы. Например,

     T array[N];
    std::vector<T> v;
    //fill v
    
    f(array, array N);      //okay
    f(v.begin(), v.end());  //also okay.
      

    Круто, не правда ли?

Комментарии:

1. И для дополнительной универсальности, template <typename It> void f(It start, It end);

2. @Mike: таким образом, код будет компилироваться для вызова аналогично f(amp;var1, amp;var2) для любых переменных var1 / var2 того же типа — что нарушает безопасность во время компиляции.

3. @MikeSeymour: Спасибо за это. Добавил это в свой пост.

4. @Vlad: Это проблема со всеми стандартными контейнерами, но суть в том, что вы должны прочитать документацию, прежде чем использовать функцию. Если вы не читаете документ, то вы можете написать такой код, независимо от того, как вы пишете функции.

5. @Nawaz: ну, безопасность во время компиляции защищает от глупых ошибок / опечаток. Представьте, что вы используете функцию как f(amp;a[0], amp;a[5]) (совершенно законно), а я прихожу и меняю все вхождения a на b , за исключением только одного по ошибке. Компилятор не поймает это. Если мы хотим оставить наших пользователей наедине с документацией, без полезной поддержки компилятора, мы могли бы также использовать самый общий void* . (Примечание в сторону: я думаю, что это проблема шаблонов C : они слишком мощные и слишком близки к макросам.)

Ответ №2:

 void YourFunction(const int myarray[]);
  

В противном случае, если вы хотите, примите любой тип

 void YourFunction(const void* myGenericArray);
  

Надеюсь, это поможет

Комментарии:

1. Этого недостаточно — вы не знаете размер массива. Кроме того, вопрос помечен C , поэтому обобщения действительно должны выполняться с использованием шаблонов, а не void* .

2. вы не можете использовать const : оператору необходимо изменить значения в массиве.

3. @Vlad, это не мое понимание требования. Массив является входным параметром. Строка является выходным параметром.

4. @MikeSeymour: Учитывая неточный вопрос, я, очевидно, могу написать только это. Однако, если вы используете функции на C , нет проблем с использованием void *, я имею в виду, вы все еще используете C как программу на C, когда используете его через функции, вместо того, чтобы работать с ним как с объектно-ориентированной программой.

Ответ №3:

 void encrypt(Arrayamp; array, /*other parameters*/)
  

подойдет, какой бы тип массива вы ни использовали.

Если ваш массив представляет собой указатель в стиле C, вы также можете просто передать его:

 void encrypt(int* array, /*other parameters*/)