2016-07-08 1 views
-2

У меня есть сомнения в самых основах C.Может кто-то прояснить этот код?

  • Я написал следующий код. Здесь, в функции add(), я ничего не возвращаю и поэтому ожидал, что выход будет какой-то ненужной или что-то вроде этого, но это не произошло. Может ли кто-нибудь объяснить мне, почему это так происходит? Пожалуйста, извините меня, если я написал что-то неправильно в коде.
  • Насколько я понимаю, я думал, что память для переменной add1 будет из стека, и, как только будет выполнена add(), вся выделенная память будет освобождена, поэтому будет отображаться некоторое значение нежелательной почты.
  • Мое ясное сомнение не возвращает ничего, как он может напечатать правильное значение?

Пример кода:

main() { 
    int x = 4, sum; 
    int n; 

    printf(" enter a number \n"); 
    scanf("%d", &n); 

    sum = add(x, n); 

    printf(" total sum = %d\n", sum); 
} 


add(int x, int n) { 
    int add1 = 0; 

    add1 = x + n; 

    //return(add1); 
} 
+5

Это неопределенное поведение. На самом деле не очень эффективно пытаться понять, что происходит. Какое бы поведение вы ни видели, не предсказуемо - оно может меняться в зависимости от ОС, компилятора, другого (даже несвязанного) кода в программе и т. Д. – kaylum

+2

какой компилятор используется? gcc не удается скомпилировать этот код ошибка: ISO C++ запрещает объявление «добавить» без типа [-fpermissive] – Evgeniy

+5

@Evgeniy: Бесполезно указывать, что делает другой язык. C не является C++, а не C. – Olaf

ответ

0

Это неопределенное поведение.

Если вы не укажете, что возвращает функция, по умолчанию будет установлено значение int. Тогда, когда у вас нет оператора return, будет не определено, что произойдет. Так что в принципе все может случиться.

Для gcc, он будет во многих системах просто возвращать некоторое «случайное» значение. В вашем случае это просто сумма. Просто «удача».

Всегда включайте предупреждения во время компиляции, например. gcc -Wall и всегда обрабатывать предупреждения, как если бы они были ошибками.

Ваш код должен выглядеть примерно так:

#include <stdio.h> 

int add(int x,int n);  // Corrected 

int main(void) // Corrected 
{ 
    int x=4,sum; 

    int n; 

    printf(" enter a number \n"); 
    scanf("%d",&n); 

    sum = add(x,n); 

    printf(" total sum = %d\n",sum); 

    return 0;  // Corrected 
} 


int add(int x,int n)  // Corrected 
{ 

    int add1=0; 

    add1 = x+n; 

    return add1;  // Removed the // to uncomment and removed unnecessary() 
} 
+2

Вы пытаетесь определить, как ведет себя поведение ** неопределенного поведения **. Это чистая спекуляция, если возвращается «случайное значение» или появляются носовые демоны. Есть и другие проблемы, совместимые со стандартным компилятором **, о которых нужно предупредить. – Olaf

+0

Да, отредактированный отредактированный код будет работать нормально, я получил его, но мой вопрос Будет ли он возвращать что-то случайным образом, даже если вы не поместите какой-либо оператор возврата? В идеале, он не должен возвращать что-либо прямо, и Stack освободит память для add1 вправо, и, следовательно, значение будет потеряно. Я запутался. может ли вы объяснить это более четко? –

+1

@ t.purnaChander - В большинстве систем простая функция, подобная этой, вернет значение, поместив значение в один из регистров ЦП. Это специфично для системы и документировано в ABI. Код в 'main' будет просто читать этот регистр и рассматривать его как возвращаемое значение. Неважно, действительно ли функция записана в регистр или нет. – 4386427

0

Как уже говорилось ранее, это неопределенное поведение, и вы не должны полагаться на него.

Однако, существует какая-то логика того, что происходит. Возвращаемое значение для функции, по соглашению, сохраняется в регистре eax на x86 или в регистре rax на x86_64. Просто бывает, что ваш компилятор также использует регистр eax или rax для хранения вычисленного значения. Кроме того, поскольку тип возврата add() не указан, он неявно определяется как int.

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