2015-03-20 7 views
0

Результат этого кода внизу должно быть 30, однако при компиляции и запуска этого дает мне следующий результатФункции и аргументы, дающие ошибку

the result of 2358968 and 0 is 4200271, a , b , result 

Я не понимаю, когда у меня нет никаких переменных это значение, как результат может быть таким?

#include<stdio.h> 
#include<conio.h> 

void add(int , int); 

int main(){ 
    add(10,20); 
    getch(); 
    return 0 ; 
} 


void add(int a, int b){ 
    int result = a + b; 
    printf("the result of the %d and %d is %d, a, b, result"); 
} 
+1

'printf (« результат% d и% d равен% d \ n ", a, b, result);' –

ответ

6

В коде

printf("the result of the %d and %d is %d, a, b, result"); 

должен быть

printf("the result of the %d and %d is %d\n", a, b, result); 
             ^
              | 
            //format string ends here 
    // arguments for format specifiers are meant to be 
    // supplied as different arguments to `printf()`, not as a part of <format> string itself 

С man page из printf()

Int Printf (Const символ * формат, ...) ;

и

Функции в выходе продукции printf() семьи согласно к format ....

Так в основном ваш код должен быть

printf("<format>", var1, var2,....); 

Прилагаемый переменными являются не часть format.

Проблема в коде отсутствовала переменные (аргументы) для заданных спецификаторов формата. В соответствии со стандартом C11, глава 7.21.6.1, пункт 2

[...] Если нет достаточных аргументов для формата, поведение не определено. [...]

Таким образом, ваш код производит undefined behaviour, распечатывает некоторую утилизацию.

Мораль истории: Если вы включили оповещения компилятора Вам компилятор должен предупредить вас об отсутствии (несоответствие) agruments в printf(). Поэтому всегда включайте предупреждения.

+0

Не помогает, просто добавив новую строку, как значения изменилось бы? –

+0

@PratikRatnaparkhi - это единственное изменение, которое вы заметили?Если да, то тогда, пожалуйста, посмотрите сложнее. :-) –

+1

Что такое подстановка синтаксиса в режиме цветной слепоты? :) – BitTickler

2

Sourav Ghosh answered для большинства вопросов; он по праву предложил включить все предупреждения при компиляции. Если ваш компилятор (особенно в Linux), некоторые последние GCC или Clang/LLVM передают -Wall -Wextra -g команде gcc или clang (чтобы получить почти все предупреждения, некоторые дополнительные и отладочную информацию). Другие варианты компилятора (-fsanitize=address и т. Д. И т. Д.) И другие инструменты (отладчик gdb, инструмент valgrind, strace, ...) тоже могут быть полезны!

Я не понимаю, когда у меня нет переменных этого значения, как результат будет таким?

Потому что вы столкнулись с undefined behavior. Читайте об этом больше (в частности, блог Лэттнера по телефону What Every C Programmer should know about Undefined Behavior), и старайтесь всегда избегать этого во всех случаях. Имейте в виду, что с UB ваша (или любая другая) программа может работать, хотя на самом деле она имеет некоторое неопределенное поведение.

Особые данные о вывозе (или, по-видимому, случайные), которые печатаются: могут не воспроизводиться и могут быть объяснены только путем погружения в каждую информацию о реализации, включая поиск машинного кода, сгенерированного вашим конкретным компилятором, и проверка состояния машины (значения регистра); конкретно printfреализация в вашей системе, вероятно, использует некоторые stdarg(3) вещи и извлекает некоторые значения из неинициализированной памяти или регистра, которая имеет некоторое предыдущее значение «мусора» (на уровне машины).

См. Также this answer (и многие другие) о неопределенном поведении. Трудно все это избежать. Помните, что при кодировании (даже в C) вы в конечном счете кодируете какую-либо виртуальную или абстрактную машину, которая не является реальным компьютером. Даже если вы записываете все уровни программного обеспечения из ядра операционной системы - это займет у вас много десятков лет как минимум - вы кодируете некоторую указанную абстракцию, и вам нужно игнорировать некоторые ошибки в работе вашего компьютера (например, если он ломается , получить некоторые космические лучи и т. д. и т. д.) за пределами этих абстракций. Спецификация операционной системы C99 или C11 (технический документ из нескольких сотен страниц на английском языке) с указанием спецификации операционной системы POSIX 2008 являются полезными абстракциями для программного обеспечения кода.

+0

Ответ был бы лучше, если бы он также сказал, что такое неопределенное поведение. – BitTickler

+1

Я дал ссылку на wikipedia UB слишком сложно объяснить в нескольких предложениях –

+0

Действительно? Как насчет: «Вы используете функцию vararg и не указываете правильное количество аргументов в соответствии с информацией, указанной в строке формата»? – BitTickler

1

заявление Printf является причиной нежелательного выхода,

printf("the result of the %d and %d is %d, a, b, result"); 

Там нет аргументов, указанных для спецификатора формата, положение " должно быть изменено.

заявление должно быть, как это

printf("the result of the %d and %d is %d", a, b, result); 

В вашем PRINTF заявлении она принимает значение мусора, так как никакие аргументы не были указаны там %d.

2

Вы закрыли " в конце строки. и в функции printf вы указали %d. Так что %d не будет иметь переменную, чтобы указать и получить значение.

Вы получите предупреждающее сообщение, %d expects a matching int

Это будет иметь значение для мусора в таком положении, поэтому она печатает какую-то ценность.

0

printf ("результат% d и% d есть% d, a, b, result"); это должно быть printf ("результат% d и% d есть% d", a, b, result); он будет читать и присваивать значение% d слева для записи. printf возвращает количество символов

Смежные вопросы