Я сказал, что была «по крайней мере одна ошибка почти на каждой строке вашего кода», и теперь я перечислил их. Если у меня нет комментариев по строке, в этой строке нет ошибок, но вам также нужно прочитать правильное форматирование и стиль кода.
int lame(unsigned int size, unsigned int value){
unsigned int array1[4];
unsigned int array2[6];
array2[5] = value;
memcpy(&array1, &array2, size * sizeof(unsigned int));
return 1;
}
Неопределенное поведение на memcpy
линии, если size
больше, чем 4. Поскольку size
берется из пользовательского ввода, эта программа содержит уязвимость переполнения буфера, хотя тот, который может быть трудно эксплуатировать. (Вам необходимо прочитать «Smashing the Stack for Fun and Profit.»)
Эта функция не имеет внешних видимых побочных эффектов. Компилятор может и, вероятно, удалит весь код, за исключением return 1
.
Функции, которые всегда возвращают одинаковое постоянное значение, должны быть реорганизованы для возврата void
. Функции, которые не используются вне текущего файла, должны быть объявлены static
.
void awesome(){
printf("awwwwwww yeaaahhhhh! All awesome, all the time!\n");
}
Это использование printf
можно заменить puts
. Функции, которые не используются вне текущего файла, должны быть объявлены static
.
main(unsigned int argc, char ** argv){
Первый аргумент main
должен иметь тип int
, не unsigned int
. Обратный тип (который должен быть int
, а не void
) отсутствует; многие компиляторы будут терпеть это (рассматривая его как неявное возвращение int
) для обратной совместимости с кодом pre-C89, но он по-прежнему неверен.
unsigned int size, value;
size = strtoul(argv[1], 0, 10);
value = strtoul(argv[2], 0, 16);
Оба size
и value
должны быть unsigned long
для соответствия с какими strtoul
возвращается.
Неопределенное поведение, если имеется менее двух аргументов командной строки.
Необходимо проверить оба звонка на strtoul
для отказа. Это нетривиально; прочитайте EXAMPLES section of the OpenBSD manpage for strtoul
, чтобы узнать, как это сделать правильно.
Однако реквизита для использования strtoul
, а не atoi
(которые вы не можете чек на отказ) или sscanf
(который имеет неопределенное поведение на целочисленное переполнение).
if(!lame(size, value)){
awesome();
}
else{
printf("I am soooo lame :(\n");
}
Компилятор может и будет определять, что lame
всегда возвращает 1, а также оптимизировать выход вызов awesome
.(Фактически, он будет иметь право оптимизировать все, но выше printf
, так как все пути управления потоком либо вызывают неопределенное поведение, либо достигают этого printf
, и других внешних видимых эффектов нет. Составителей, с которыми я с готовностью не совсем, что умные, но они сделать удалить тогда еще, если-и весь код внутри lame
.)
Это использование printf
также может быть заменен puts
.
Вы автоматически станете на 23% меньше, если перестанете называть себя хромым.
return 0xdeadbeef;
Значение, возвращаемое main
имеет смысл. 0 означает успех общей программы, любое другое значение означает какой-то отказ. Всегда возвращайте 0, если вы не намерены указывать отказ. Кроме того, только исходные значения в диапазоне [0, 127] могут быть надежно получены кросс-платформой родительского процесса; 0xdeadbeef
Правильно.
На вашем скриншоте main
void
вместо отсутствия возвращаемого типа; что плюс оператор return
со значением должен был привести к ошибке компиляции. Однако ваш компилятор может переносить его в main
.
Не размещайте ссылку на код. В частности, не размещайте ссылку на IMAGE кода. Поместите здесь свой код – Joe
. Прежде всего, не публикуйте ссылки на код, ссылки могут устаревать и сделать ваш вопрос бесполезным. Во-вторых, и, что более важно, не размещайте изображения текста! Это делает невозможным копирование и вставку, чтобы попробовать сами. Вместо этого вы должны скопировать и вставить текст и поместить в тело вопроса как текст. –
Существует по крайней мере одна ошибка почти на каждой строке вашего кода. Вам нужен вводный курс программирования, а не сайт Q & A. – zwol