2013-06-18 5 views
1

Я ожидаю, что выход будет «Sunday Monday», но фактический результат «понедельник понедельник», почему это?неправильный вывод из простого кода кода C

#include <stdio.h> 
#include <string.h> 
static const char *msg[] = {"Sunday", "Monday", 
"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 
char *get_a_day(int idx) 
{ 
    static char buf[20]; 
    strcpy(buf, msg[idx]); 
    return buf; 
} 

int main(void) 
{ 
    printf("%s %s\n", get_a_day(0), get_a_day(1)); 
    return 0; 
} 
+0

Что происходит, если вы используете отдельные вызовы 'printf'? – AJMansfield

+0

жаль, что я забыл написать «возврат» в последнем редактировании ... моя ошибка –

ответ

3

Вы объявляете buf[] в static, что означает, что будет именно одна ячейка памяти всеми экземплярами.

get_a_day(), кажется, неявным образом возвращают buf[], поэтому оба вызова на get_a_day() возвращают указатель на тот же буфер.

Первый набор вызовов buf[] - "Sunday" и возвращает указатель на ячейку памяти buf. Затем второй вызов устанавливает buf[] по номеру "Monday", переписывая "Sunday" и возвращает указатель на ячейку памяти buf - та же ячейка памяти, что и первый звонок. Затем указатель на buf передается как 2-й и 3-й аргументы в printf. С buf содержит "Monday" (ранее переписанный "Sunday"), printf() отпечатки Monday Monday.

Почему buf должен быть статическим? Если вы удалите это ключевое слово и правильно распределите свою память, все должно работать так, как вы надеялись. Кроме того, вам нужно buf? Если вы только что вернули msg[i], вы получите ожидаемый результат.

Еще одна вещь: вы не должны неявно возвращать такое значение. Ремонтопригодность существенно снижается, и цель кода не ясна. Вы должны явно указать значение, которое вы хотите вернуть.

+0

Ты мне очень помог. благодаря! –

2

Вы должны включить все предупреждения (например, компилировать с gcc -Wall -g) и научиться использовать отладчик (например, gdb).

Обратите внимание, что функция get_a_day объявлена ​​для возврата char*, но ничего не возвращает (и ваш компилятор предупредит вас об этом). Таким образом, у вас есть undefined behavior, и все может случиться (и по-прежнему соответствует спецификациям C).

Даже если добавить return buf; в конце вашей get_a_day функции, она будет возвращать же указатель, поскольку buf является static (если вызывается дважды в printf, как вы делаете).

Возможно, вам стоит рассмотреть вопрос о возврате выделенной кучи строки и иметь соглашение о том, что вызывающий абонент должен освободить его. Но в вашем конкретном случае достаточно возврата msg[idx].

+0

Yep должен выделять новый буфер и удалять его в конце. Плюс все без возврата. – MrMoDoJoJr

+0

Он ничего не возвращает, И заполняет локальный буфер 'buf', который затем сразу же выходит из существования. Он, очевидно, хотел вернуть «buf», но это тоже не сработает (актуален, возможно, он работает, несмотря на то, что он ошибается). –

+1

@LeeDanielCrocker: обратите внимание, что 'buf' объявлен' static', поэтому код не возвращает локальный буфер. –

2

Потому что вы используете strcpy. strcpy заменяет всю строку в буфере. Таким образом, второй вызов перезаписывает первый вызов (на некоторых платформах первый вызов будет перезаписывать второй вызов, потому что они оцениваются в обратном порядке). Не говоря уже о отсутствии возврата. Попробуйте использовать этот код вместо этого:

char* get_a_day(int idx, char* buf) 
{ 
    strcpy(buf, msg[idx]); 
    return buf; 
} 

int main(void) 
{ 
    char buf0[20]; 
    char buf1[20]; 

    printf("%s %s\n", get_a_day(0, buf0), get_a_day(1, buf1)); 
    return 0; 
} 
+0

спасибо, я думаю, что ваш код хорошо работает –

3

Если вы хотите получить объяснение, другие ответы объясняют это хорошо.

Если вы просто хотите, чтобы ваша программа работала, это должно исправить:

const char *get_a_day(int idx) 
{ 
    return msg[idx]; 
} 
+0

ye Я его вижу^_^спасибо –

Смежные вопросы