Эффекты ключевого слова экстерна на функциях C

Метод pygame.Rect.move_ip не возвращает никакого значения. Он изменяет сам объект pygame.Rect .

Таким образом, после

textrect = textrect.move_ip(-50, -50)
blockquote>

значение textrect равно None.

Далее отметим, что верхняя правая координата a Surface равна ( widht , 0). Если вы хотите перейти к центру поверхности, то вам нужно двигаться в отрицательном направлении x, но в положительном направлении y, а не в отрицательном направлении y.

Для решения вашей проблемы это должно быть:

displayfont = pygame.font.SysFont(None, 30)
text = displayfont.render('level', True, (red), (white))
textrect = text.get_rect()
textrect.topright = screen.get_rect().topright

textrect.move_ip(-50, 50)  

screen.blit(text, textrect)

162
задан undur_gongor 14 July 2015 в 08:09
поделиться

7 ответов

We have two files, foo.c and bar.c.

Here is foo.c

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

Now, here is bar.c

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   while (! stop_now) {
      printf("Hello, world!\n");
      sleep(30);
   }
}

As you can see, we have no shared header between foo.c and bar.c , however bar.c needs something declared in foo.c when it's linked, and foo.c needs a function from bar.c when it's linked.

By using 'extern', you are telling the compiler that whatever follows it will be found (non-static) at link time; don't reserve anything for it in the current pass since it will be encountered later. Functions and variables are treated equally in this regard.

It's very useful if you need to share some global between modules and don't want to put / initialize it in a header.

Technically, every function in a library public header is 'extern', however labeling them as such has very little to no benefit, depending on the compiler. Most compilers can figure that out on their own. As you see, those functions are actually defined somewhere else.

In the above example, main() would print hello world only once, but continue to enter bar_function(). Also note, bar_function() is not going to return in this example (since it's just a simple example). Just imagine stop_now being modified when a signal is serviced (hence, volatile) if this doesn't seem practical enough.

Externs are very useful for things like signal handlers, a mutex that you don't want to put in a header or structure, etc. Most compilers will optimize to ensure that they don't reserve any memory for external objects, since they know they'll be reserving it in the module where the object is defined. However, again, there's little point in specifying it with modern compilers when prototyping public functions.

Hope that helps :)

131
ответ дан 23 November 2019 в 21:22
поделиться

Вам необходимо различать две отдельные концепции: определение функции и объявление символа. «extern» - это модификатор связи, подсказка компилятору о том, где определен символ, на который впоследствии ссылаются (подсказка «не здесь»).

Если я напишу

extern int i;

в области видимости файла (вне функционального блока) ) в файле C, то вы говорите, что «переменная может быть определена в другом месте».

extern int f() {return 0;}

- это и объявление функции f, и определение функции f. Определение в этом случае имеет приоритет над extern.

extern int f();
int f() {return 0;}

- это сначала объявление, за которым следует определение.

Использование extern неверно, если вы хотите объявить и одновременно определить переменную области видимости файла , Например,

extern int i = 4;

выдаст ошибку или предупреждение, в зависимости от компилятора.

Использование extern полезно, если вы явно хотите избежать определения переменной.

Позвольте мне объяснить:

Допустим, файл ac содержит:

#include "a.h"

int i = 2;

int f() { i++; return i;}

Файл ah включает:

extern int i;
int f(void);

и файл bc содержит:

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

int main(void){
    printf("%d\n", f());
    return 0;
}

Экстерн в заголовке полезен, потому что он сообщает компилятору во время фазы компоновки: «Это объявление, а не определение». Если я удалю строку в ac, которая определяет i, выделю для нее место и присвою ей значение, программа не сможет скомпилировать с неопределенной ссылкой. Это сообщает разработчику, что он ссылался на переменную, но еще не определил ее. Если, с другой стороны, я опущу ключевое слово extern и уберу строку int i = 2 , программа все равно компилируется - i будет определен со значением по умолчанию 0.

Переменные области видимости файла неявно определяются со значением по умолчанию 0 или NULL, если вы явно не присваиваете им значение - в отличие от переменных области видимости блока, которые вы объявляете в верхней части функции. Ключевое слово extern позволяет избежать этого неявного определения и, таким образом, помогает избежать ошибок.

Для функций в объявлениях функций ключевое слово действительно является избыточным. Объявления функций не имеют неявного определения.

21
ответ дан 23 November 2019 в 21:22
поделиться

As far as I remember the standard, all function declarations are considered as "extern" by default, so there is no need to specify it explicitly.

That doesn't make this keyword useless since it can also be used with variables (and it that case - it's the only solution to solve linkage problems). But with the functions - yes, it's optional.

76
ответ дан 23 November 2019 в 21:22
поделиться

The extern keyword takes on different forms depending on the environment. If a declaration is available, the extern keyword takes the linkage as that specified earlier in the translation unit. In the absence of any such declaration, extern specifies external linkage.

static int g();
extern int g(); /* g has internal linkage */

extern int j(); /* j has tentative external linkage */

extern int h();
static int h(); /* error */

Here are the relevant paragraphs from the C99 draft (n1256):

6.2.2 Linkages of identifiers

[...]

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,23) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

14
ответ дан 23 November 2019 в 21:22
поделиться

Встроенные функции имеют специальные правила о том, что означает extern . (Обратите внимание, что встроенные функции являются расширением C99 или GNU; их не было в исходном C.

Для не встроенных функций, extern не требуется, поскольку он включен по умолчанию.

Примечание. что правила для C ++ другие. Например, extern "C" необходим для объявления C ++ функций C, которые вы собираетесь вызывать из C ++, и существуют другие правила для inline .

9
ответ дан 23 November 2019 в 21:22
поделиться

The extern keyword informs the compiler that the function or variable has external linkage - in other words, that it is visible from files other than the one in which it is defined. In this sense it has the opposite meaning to the static keyword. It is a bit weird to put extern at the time of the definition, since no other files would have visibility of the definition (or it would result in multiple definitions). Normally you put extern in a declaration at some point with external visibility (such as a header file) and put the definition elsewhere.

3
ответ дан 23 November 2019 в 21:22
поделиться

Причина, по которой он не действует, заключается в том, что во время компоновки компоновщик пытается разрешить определение extern (в вашем случае extern int f () ). Неважно, найдет ли он его в том же или другом файле, если он найден.

Надеюсь, это ответ на ваш вопрос.

1
ответ дан 23 November 2019 в 21:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: