C Puzzle - играть с типами - PullRequest
9 голосов
/ 13 ноября 2009

Пожалуйста, проверьте следующую программу.

#include <stdio.h>

struct st
{
 int a ;
}

fn ()
{
 struct st obj ;
 obj.a = 10 ;

 return obj ;
}

int main()
{
 struct st obj = fn() ;

 printf ("%d", obj.a) ;
}

Ниже приведены вопросы

  1. Какой вывод программы?
  2. Где ';' прекратить объявление 'struct st'?

    По ИСО МЭК 9899 - 1999 спецификация, декларация должна заканчиваться на «;».

        declaration-specifiers init-declarator-listopt ;
    
  3. Если объявление структуры St 'берется, представляя только возвращаемый тип функция 'FN', как это видно к другим функциям (основным)?

Ответы [ 2 ]

9 голосов
/ 13 ноября 2009
  1. Выход 10. 10. 1002 *
  2. Не должно быть точки с запятой, потому что все это определение функции.
  3. Тег структуры st объявлен в глобальной области видимости и поэтому видим для основного.
5 голосов
/ 13 ноября 2009

Вещи могут быть немного яснее, если мы немного переформатируем код:

struct st { int a; } fn() 
{
  struct st obj;
  obj.a = 10;
  return obj;
}
int main()
{
  struct st obj = fn();
  printf("%d\n", obj.a);
  return 0;
}

Таким образом, тип возврата fn() равен struct st {int a;}. После определения структуры нет точки с запятой, поскольку тип структуры является частью определения функции (проследите по грамматике от translation-unit -> top-level-declaration -> function-definition). Тип структуры доступен для main(), потому что вы поместили тег структуры в него (st). Вы написали

struct { int a; } fn() {...}

тогда тип не был бы доступен для main(); вам бы пришлось создать новый тип структуры с таким же определением.

Вы получаете такой же эффект, как если бы вы написали

struct st {
  int a; 
};

struct st fn() 
{ 
  /* same as before */
}

int main()
{
  /* same as before */
}
...