Я попробовал приведенный ниже код, так как у меня нет поддержки китайского, я не могу его протестировать.
var latinPresentation1 = "some text" ;
var latinPresentation2 = "some longer text";
Console.WriteLine(String.Format("{0,-30} {1,-10} ", latinPresentation1, "| " + 23));
Console.WriteLine(String.Format("{0,-30} {1,-10} ", latinPresentation2, "| " + 23));
Console.WriteLine("..............................................");
var chinesePresentation1 = "一些文字";
var chinesePresentation2 = "一些較長的文字";
Console.WriteLine(String.Format("{0,-30} {1,-10} ", chinesePresentation1, "| " + 23));
Console.WriteLine(String.Format("{0,-30} {1,-10} ", chinesePresentation2, "| " + 23));
You are trying to call do_something before you declare it. You need to add a function prototype before your printf line:
char* do_something(char*, const char*);
Or you need to move the function definition above the printf line. You can't use a function before it is declared.
Когда компилятор увидел ваш вызов do_something()
, он посмотрел на то, как он был вызван, и пришел к выводу, что do_something()
в конечном итоге будет объявлено так:
int do_something(char arg1[], char arg2[])
{
...
}
Почему он пришел к выводу, что ? Потому что именно так вы назвали это! (Некоторые компиляторы C могут прийти к выводу, что это было int do_something(int arg1, int arg2)
или просто int do_something(...)
, оба из которых даже дальше от того, что вы хотите, но важно то, что независимо от того, как компилятор угадывает типы он угадывает их не так, как использует ваша фактическая функция.)
Позже, когда компилятор просматривает файл вперед, он видит ваше фактическое объявление для char *do_something(char *, char *)
. Это объявление функции даже не близко к объявлению, которое угадал компилятор, что означает, что строка, в которой компилятор скомпилировал вызов, была скомпилирована неправильно, и программа просто не будет работать. Таким образом, он правильно выводит ошибку, сообщающую, что ваш код не будет работать так, как написано.
Вы можете спросить: «Почему предполагается, что я возвращаю int
?» Ну, он предполагает этот тип, потому что нет никакой информации об обратном: printf()
может принимать в любой тип в своих переменных-аргументах, поэтому без лучшего ответа int
является такой же догадкой, как и любая другая. (Многие ранние компиляторы C всегда предполагали int
для каждого неопределенного типа и предполагали, что вы имели в виду ...
для аргументов для каждой объявленной функции f()
, а не void
- поэтому многие современные стандарты кода рекомендуют всегда ставить void
] для аргументов, если на самом деле их не должно быть.)
Исправление
Существует два распространенных исправления ошибки объявления функции.
Первое решение, которое рекомендуется многими другими ответами здесь, состоит в том, чтобы поместить прототип в исходный код над местом, где функция сначала вызывается. Прототип выглядит так же, как объявление функции, но имеет точку с запятой, где тело должно быть следующим:
char *do_something(char *dest, const char *src);
Если поставить прототип первым, то компилятор знает , что функция в конечном итоге будет выполнять. похоже, так что не надо догадываться. По соглашению, программисты часто помещают прототипы в верхнюю часть файла, прямо под операторами #include
, чтобы гарантировать, что они всегда будут определены до любого их потенциального использования.
Другое решение, которое также появляется в некотором реальном коде, состоит в том, чтобы просто переупорядочить ваши функции так, чтобы объявления функций всегда были перед чем-нибудь, что их вызывает! Вы можете переместить всю функцию char *do_something(char *dest, const char *src) { ... }
выше первого вызова, и тогда компилятор точно будет знать, как выглядит функция, и не должен будет угадывать.
На практике большинство людей используют прототипы функций, потому что вы также можете взять прототипы функций и переместить их в файлы заголовков (.h
), чтобы код в других файлах .c
мог вызывать эти функции. Но любое решение работает, и многие кодовые базы используют оба.
C99 и C11
Полезно отметить, что правила немного отличаются в более новых версиях стандарта C. В более ранних версиях (C89 и K & amp; R) компилятор действительно будет угадывать типы во время вызова функции (а компиляторы K & amp; R-эры часто даже не предупреждают вас, если они ошибаются) , C99 и C11 требуют, чтобы объявление функции / прототип предшествовало первому вызову, и если это не так, это ошибка. Но многие современные компиляторы C - главным образом для обратной совместимости с более ранним кодом - только предупреждают об отсутствующем прототипе и не считают это ошибкой.
In "classic" C language (C89/90) when you call an undeclared function, C assumes that it returns an int
and also attempts to derive the types of its parameters from the types of the actual arguments (no, it doesn't assume that it has no parameters, as someone suggested before).
In your specific example the compiler would look at do_something(dest, src)
call and implicitly derive a declaration for do_something
. The latter would look as follows
int do_something(char *, char *)
However, later in the code you explicitly declare do_something
as
char *do_something(char *, const char *)
As you can see, these declarations are different from each other. This is what the compiler doesn't like.
You didn't declare it before you used it.
You need something like
char *do_something(char *, const char *);
before the printf.
Example:
#include <stdio.h>
char *do_something(char *, const char *);
char dest[5];
char src[5] = "test";
int main ()
{
printf("String: %s\n", do_something(dest, src));
return 0;
}
char *do_something(char *dest, const char *src)
{
return dest;
}
Alternatively, you can put the whole do_something
function before the printf.
You have to declare the function before you use it. If the function name appears before its declaration, C compiler will follow certain rules and makes the declaration itself. If it is wrong, you will get that error.
You have two options: (1) define it before you use it, or (2) use forward declaration without implementation. For example:
char *do_something(char *dest, const char *src);
Note the semicolon at the end.
Заповедь C № 3:
K&R #3 Thou shalt always prototype your functions or else the C compiler will extract vengence.
http://www.ee.ryerson.ca:8080/~elf/ hack / God.vs.K + R.html
When you don't give a prototype for the function before using it, C assumes that it takes any number of parameters and returns an int. So when you first try to use do_something, that's the type of function the compiler is looking for. Doing this should produce a warning about an "implicit function declaration".
So in your case, when you actually do declare the function later on, C doesn't allow function overloading, so it gets pissy because to it you've declared two functions with different prototypes but with the same name.
Short answer: declare the function before trying to use it.