2014-09-03 2 views
1

Для задания домашней работы мы должны написать короткую программу, которая сообщает вам количество аргументов, переданных в main, их адрес данных и каждый аргумент, используя argc и argv. Нам также пришлось написать функцию strlen (нам не разрешалось использовать какие-либо подобные функции, включенные в библиотеку), которые вычисляли длину каждого аргумента, переданного в main, с помощью указателей. Моя функция всегда возвращает 0. Извините, что задаю такой основной вопрос, но, будучи учеником первого курса, я еще не обучен использованию отладчика. Вот мой код:Функция strlen всегда возвращается 0

int strlen(char * p) 
{ 
    char X[50]; 
    p = &X[0]; 
    int i = 0; 

    while (*(p + i) != '\0') 
     i++; 

    return i; 
} 

Я пытался несколько различных вещей, чтобы исправить это, но независимо от того, что функция всегда кажется, возвращает значение 0. Есть ли вопиюще огромная проблема я с видом? Любой толчок в правильном направлении был бы полезен, но, пожалуйста, не просто дайте мне ответ.

+1

Вы присваиваете значение '& X [0]' ** to ** 'p' здесь -' p = &X[0]; ' –

+6

", пожалуйста, не просто дайте мне ответ "- попробуйте [Rubber Duck Debugging] (http : //en.wikipedia.org/wiki/Rubber_duck_debugging). Объясните утке, что должен делать 'X'. –

+0

Если у вас нет аргументов в пользу 'char X [50];' и 'p = &X[0];', вы можете просто удалить эти строки. –

ответ

5

Вы написали функцию, которая вычисляет длину локальной «строки» X. Массив X даже не инициализирован. Он содержит мусор. Ваша функция возвращает длину этой строки мусора. Это не обязательно 0, это просто случайно оказалось нулевым в ваших экспериментах. В общем случае ваша функция вернет значение мусора или просто приведет к сбою вашей программы. Поведение не определено.

Иными словами, когда вы вызываете вашу функцию как strlen("hello"), строка "hello" полностью игнорируется кодом, который вы написали. Ваша функция по-прежнему настаивает на работе с локальным массивом X, а не с аргументной строкой "hello", прошедшей снаружи.

Если это вы, который написал эту функцию, это действительно вопрос для вас: почему вы так поступили?

P.S. Более разумная реализация strlen, вероятно, получит параметр const char * (не char *) и выполнить подсчет в домене size_t (не int).

P.P.S. *(p + i) эквивалентен p[i]. Многие считают, что последние более читабельны, чем первые.

+0

Спасибо! Я знал, что это было что-то очевидное, но я не обратил на это внимания. Моя программа работает по назначению. – gsoble

0

Просто избавитесь от первых двух линий.

int strlen(char * p) 
{ 
    int i = 0; 
    while (*(p + i) != '\0') 
     i++; 

    return i; 
} 

Рабочий пример: http://ideone.com/8R8Elu

1

Прежде всего, ваша функция не имеет смысла; он перезаписывает параметр, а массив X не инициализируется, поэтому его элементы имеют некоторые неуказанные значения, а программа, использующая эту функцию, имеет неопределенное поведение. функция может выглядеть следующим образом:

size_t strlen(const char * p) 
{ 
    size_t i = 0; 

    while (*(p + i) != '\0') i++; 

    return i; 
} 

Или более читабельным

size_t strlen(const char * p) 
{ 
    size_t i = 0; 

    while (p[i] != '\0') i++; 

    return i; 
} 

Например

#include <iostream> 

size_t strlen(const char * p) 
{ 
    size_t i = 0; 

    while (p[i] != '\0') i++; 

    return i; 
} 

int main() 
{ 
    char s[] = "Hello gsoble"; 

    std::cout << "The size of the greeting is " << strlen(s) << std::endl; 
} 
0

Это неопределенное поведение. Вы проходите массив X до '\0', но '\0' может никогда не произойти, поскольку X - это локальный объект с неопределенным значением. Вместо этого вы можете столкнуться с ошибкой сегментации.

Есть ли невероятно огромная проблема, которую я рассматриваю?

Вам не нужен локальный массив. Вы можете начать только с

size_t strlen(const char * p) // take const for safety reasons 
{        // and return size_t for compatibility 
    size_t i = 0; 
    while (*(p + i) != '\0') ++i; 

    return i; 
} 
+0

@BenVoigt: ожидается, что 'strlen (X)' в коде в вопросе, но 'X' - это не то, что функция должна смотреть, а на самом деле' X' вовсе не требуется. –

0

Как и другие ответы объяснить, вы настраиваете p равным неинициализированного x здесь, что даст вам неопределенное поведение. Что другой ответ не дают вам однако, ..... рекурсии (потому что почему нет)

unsigned strlen(const char *p) { 
    if(*p == '\0') return 0; 
    return 1 + strlen(p+1); 
} 

И если вы хотите, чтобы получить его до 1 линии:

unsigned strlen(const char *p) { 
    return (*p == '\0') ? 0 : 1 + strlen(p+1); 
} 
Смежные вопросы