#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*/)