Попробуйте, предположив, что в вашем инвентаре нет повторяющихся предметов, иначе он потерпит крах при хранении предметов в словаре. это, но во избежание проблем, я бы использовал список проверки данных на листе получения, чтобы подобрать продукт, который подается в инвентарном листе. Таким образом, не будет проблем с поиском некоторых продуктов для опечаток.
Получение указателя снова вместо значения:
Каждый обычно использует адресную арифметику с указателями, когда они хотят получить указатель снова. Получить указатель при использовании индекса массива: Вам 1 год), вычисление смещения указателя, затем 2) получая значение в той ячейке памяти, затем 3) необходимо использовать и получить адрес снова. Это больше вводит и менее чистый синтаксис.
Пример 1: Скажем, Вам нужен указатель на 512-й байт в буфере
char buffer[1024]
char *p = buffer + 512;
Является более чистым, чем:
char buffer[1024];
char *p = &buffer[512];
Пример 2: более эффективный strcat
char buffer[1024];
strcpy(buffer, "hello ");
strcpy(buffer + 6, "world!");
Это более чисто, чем:
char buffer[1024];
strcpy(buffer, "hello ");
strcpy(&buffer[6], "world!");
Используя адресную арифметику с указателями ++ как итератор:
Постепенное увеличение указателей с ++ и постепенное уменьшение с - полезны при итерации по каждому элементу в массиве элементов. Это более чисто, чем использование отдельной переменной раньше отслеживало смещение.
Вычитание указателя:
Можно использовать вычитание указателя с адресной арифметикой с указателями. Это может быть полезно в некоторых случаях для получения элемента перед тем, на который Вы указываете. Это может быть сделано с нижними индексами массива также, но это выглядит действительно плохо и выглядит сбивающим с толку. Особенно программисту Python, где отрицательный нижний индекс дан для индексации чего-то от конца списка.
char *my_strcpy(const char *s, char *t) {
char *u = t;
while (*t++ = *s++);
return u;
}
Почему Вы хотели бы испортить такую красоту с индексом? (См. K&R, и как они основываются до этого стиля.) Существует причина, я использовал вышеупомянутую подпись путем, это. Прекратите редактировать, не прося разъяснение сначала. Для тех, кто думает, что знают, ищите существующую подпись - Вы скучали по некоторым restrict
квалификации.
Тестирование выравнивания структуры и offsetof
макро-реализация.
При использовании старого компилятора или некоторого компилятора встроенных систем специалиста могли бы быть небольшие различия в производительности, но самые современные компиляторы, вероятно, оптимизируют эти (крошечные) различия.
Следующая статья могла бы быть чем-то, что Вы могли привлечь - зависит на уровне Ваших студентов:
итерация через 2-мерный массив, где положение данной величины действительно не имеет значения
если бы Вы не используете указатели, необходимо было бы отслеживать два нижних индекса
с указателями Вы могли указать на вершину своего массива, и с единственным циклом, zip через все это
Вы спрашиваете о C а именно, но C++ полагается на это также:
Большая часть адресной арифметики с указателями естественно делает вывод к Вперед понятие Итератора. Обход через память с *p++
может использоваться для любого упорядоченного контейнера (связанный список, пропустите список, вектор, двоичное дерево, B дерево, и т.д.), благодаря перегрузке оператора.
Что-то забава, я надеюсь Вы, никогда не должно иметь дело с: указатели могут исказить, тогда как массивы не могут. Искажение может вызвать все виды неидеальной генерации кода, наиболее распространенный из которых использует указатель в качестве параметр к другой функции. В основном компилятор не может предположить, что указатель, используемый функцией, не искажает себя или что-либо еще в том стековом фрейме, таким образом, это должно перезагрузить значение от указателя каждый раз, когда это используется. Или скорее для сейфа это делает.
Часто выбором является только один из стиля - каждый смотрит или чувствует себя более естественным, чем другой для особого случая.
Существует также аргумент, что использование индексов может заставить компилятор должным быть неоднократно повторно вычислять смещения в цикле - я не уверен, как часто дело обстоит так (кроме в неоптимизированных сборках), но я предполагаю, что это происходит, но это - вероятно, редко проблема.
Одна область, что я думаю, важна в конечном счете (который не мог бы относиться к вводному классу C - но изучить их рано, я говорю), то, что использование адресной арифметики с указателями относится к идиомам, используемым в STL C++. Если Вы заставите их понимать адресную арифметику с указателями и использовать ее, то, когда они идут дальше к STL, у них будет участок о том, как правильно использовать итераторы.
Арифметика указателя может выглядеть причудливой и «хакерской», но я никогда не встречал случая, чтобы она была БЫСТРЕЕ, чем стандартное индексирование. Напротив, я часто встречал случаи, когда это сильно замедляло код.
Например, типичный последовательный цикл по массиву с указателем может быть менее эффективным, чем цикл с классическим индексом на современных процессорах, поддерживающих расширения SSE. Арифметика указателей в цикле в достаточной степени блокирует компиляторы от выполнения векторизации цикла, что может дать типичный прирост производительности в 2-4 раза. Кроме того, использование указателей вместо простых целочисленных переменных может привести к ненужным операциям хранения в памяти из-за наложения указателей.
Таким образом, НИКОГДА не рекомендуется использовать арифметику указателей вместо стандартного индексированного доступа.