Ваш код будет вызывать неопределенное поведение в обоих сегментах.(Даже если вы заметили, что код 2
работает , он работает только . На самом деле, сбой скрывается ,и может отображаться без предупреждения.)
Внесите эти исправления для решения этой проблемы и просмотрите комментарии для объяснений:
В код 1 :
//int main(void){
int main(void){//int main(void) is minimum prototype for main function.
//char example[10]; // this will invoke undefined behavior
char example[10] = {"something"}; // 'example' initialized with content,
// thus averting undefined behavior
//example=foo(example);
strcpy (example, foo(example)); // char array is not assignable using `=`
// use strcpy to transfer result of "foo"
printf("%s\n",example);
return 0;
}
char *foo(char arr[]) //note: char arr[] decays into char *arr
{
//char arr[10]="attempt"; // Error: redefinition of 'arr' with a
// different type: char[10] vs char *
arr = "attempt"; //because char [] decays into char *, 'arr' is usable as is.
return arr;
}
Чтобы ответить на ваш вопрос в комментариях: Зачем использовать функцию strcpy [ после переменной пример было инициализировано ] не является неопределенным поведением .
Во-первых, важно знать определение строки C.( Определение строки C находится здесь .)
Переменная example
в ее первоначальном виде, то есть инициализирована:
char example[10];
Может содержать что угодно.Например:
|%|h|8|\#|d|o|-|~|*|U|?|?|?|?|
// ^end of memory for 'example`
// note that the character in example[9] == 'U', not NULL, therefore, not a C string.
Это приведет к сбою функции strcpy()
.Инициализация гарантирует предсказуемые результаты:
char example[10] = {"something"};//properly initialized
|s|o|m|e|t|h|i|n|g|0|?|?|?|?|
// ^end of memory for 'example`
//or
char example[10] = {0}; //also properly initialized
|0|0|0|0|0|0|0|0|0|0|?|?|?|?|
// ^end of memory for 'example`
(This would require an extra step to place proper content.):
strcpy(example, "something");
Единственное необходимое корректировка Код 2 - инициализация указателя перед использованием: (См.причина, по которой указатель должен быть инициализирован здесь .)
char *foo(char*);
//int main(void){
int main(void){//int main(void) is minimum prototype for main function.
{
//char *example; // passing this will envoke undefined behavior
char *example = NULL;// must initialize before using
example=foo(example);
printf("%s\n",example);
return 0;
}
char *foo(char* arr)
{
arr="attempt";
return arr;
}