Функция автоматически возвращает указатель без оператора возврата - PullRequest
0 голосов
/ 09 июня 2018

Как функция fun возвращает указатель на созданный узел, хотя я не использовал никаких операторов return.Следовательно, значение в узлах будет успешно напечатано.Как?

#include <stdio.h>
#include"stdlib.h"

struct node
{
  int data;
  struct node *next;
};

main ()
{
  struct node *nl=fun();
  printf("%d",nl->data);
}

fun ()
{
    struct node *p= (struct node*)malloc(sizeof (struct node));
    scanf("%d", &(p->data));
    p->next=NULL;
}

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

Для этого оператора

struct node *nl=fun(); /* here nl expecting something from fun() but 
                      you didn't return anything, in your case default int is  
                      returning, which can cause serious problem as 
                      nl expects valid address */

ваш компилятор мог предупредить вас как

error: тип возвращаемого значения по умолчанию равен 'int' [-Werror = return-type]

Если вы скомпилировали программу с опцией -Wall -Wstrict-prototypes -Werror, в противном случае поведение будет undefined .

правильная версия может быть

struct node* fun (void) {
        struct node *p= malloc(sizeof (struct node)); /* avoid casting result of malloc() */
        scanf("%d", &(p->data));
        p->next=NULL;
        return p; /* return the dynamic memory so that you can do 
                     nl->data in main() as you are doing */
}

Также просто main () { /*code */ } не является хорошей практикой, используйте int main(void) { /* code */ }, как указано в стандарте C здесь https://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p2.

0 голосов
/ 09 июня 2018

В старых версиях C функции не могли указывать тип возвращаемого значения, и тип возвращаемого значения был автоматически int.

И если объявлялась функция, возвращающая значение (явно или как в вашем случае неявно)) затем он должен вернуть значение, иначе у вас будет неопределенное поведение .

Также обратите внимание, что в более старых версиях C компиляторавтоматически объявлять функции, которые он никогда раньше не видел при вызове.И этот, и неявный тип возврата очень подвержены ошибкам и поэтому были удалены с помощью стандарта C99.


Наконец, примечание об использовании int для указателей: часто в истории компьютеров, указателях и int не равныНапример, в наши дни в 64-битной системе указатели обычно составляют 64 бита, а int - 32 бита.Вы не можете поместить 64-битный указатель в 32-битный int, независимо от того, как сильно вы пытаетесь.Это одна из причин, по которой вы никогда не должны разыгрывать результат malloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...