2013-02-14 3 views
0

У меня возникли проблемы с пониманием этого кода. Почему длина 3? Если я ввода hi, длина 1.Почему указанная длина строки одна?

#include <stdlib.h> 
#include <stdio.h> 

int len(char *s) 
{ 
    int i = 0; 
    while(*(++s) != '\0') 
     i++; 
    printf("%d", i); 
    return i; 
} 

int main() 
{ 
    len("this"); 
    getchar(); 
} 
+1

Является ли длина 3 или 1? Не могли бы вы перефразировать вопрос. Немного «непрозрачный» – junix

+0

длина равна 3 при вызове функции len и передаче «this» в качестве аргумента, где, как если бы вы передавали пресс-форму «hi», длина равна 1. – 2013-02-14 06:09:02

+0

Спасибо за очистку. Я понял это тем временем и опубликовал объяснение. – junix

ответ

0

++s увеличивает значение перед оценкой его. Вот почему ваш ответ меньше, чем фактическая длина. Используйте s++.

0

++s - префиксный прирост, поэтому цикл будет начинаться со второго символа. Кратчайшее исправление, чтобы изменить его к постфиксу приращению:

while(*(s++) != '\0') 

В качестве альтернативы:

while(*s++) 
+0

Спасибо, я понимаю. – 2013-02-14 06:12:47

0

После прочтения вопроса несколько раз, я понимаю, что функция «Лен» возвращает 1 для строки с длиной 2 (например, «привет»)

Это из следующей строки: while (*(++s)!='\0')

рассекает результаты условий в следующих заявлений (только т о ясно, что происходит с вашим кодом, конечно, это не так, как это должно быть сделано)

startover: 
    s = s + 1; 
    if (*s != '\0') goto end; 
     i = i + 1; 
    goto startover; 

Как вы можете видеть, что вы всегда шаг за первый символ, прежде чем начать подсчет. Вы можете избежать этого, используя вместо этого s++. Это сдвинет модификацию с после проверки на «\ 0»:

startover: 
    if (*s != '\0') goto end; 
     s = s + 1; 
     i = i + 1; 
    goto startover; 
1

не только длина от 1, но если вы дадите ему пустую строку в качестве аргумента, где вы хотите его return 0, вы можете столкнуться с нарушением доступа (хотя большую часть времени вы не будете, потому что нулевые байты довольно распространены в неинициализированной памяти) или случайное число (в основном это вернет число ненулевых байтов, которые . хранится 1 байты позади с-струнной пустой строковой константой

длина отстоит от 1, потому что вы используете префикс инкрементного оператор, который вычисляется как первое, что в строке:

while(*(++s)!='\0') 

В частности, если вы посмотрите на то, что вы там делаете, долговременно руку, он будет читать так:

char *s = "this"; 
int i = 0; 

while (1) { 
    s = s + 1; 
    if (*s == '\0') break; 
    i++; 
} 
printf("%d", i); 
... 

Вы видите проблему? ++s увеличивает указатель на первое место. Таким образом, вы пропускаете первую букву строки.

Во всяком случае, то, что вы, вероятно, хотите что-то вроде этого:

int len(const char *s) { 

    int clen = 0; 
    while (*s++ != '\0') clen++; 
    return clen; 

} 

Конечно, можно было бы спросить, почему вы повторно изобретать колесо, когда у вас есть strlen() и strnlen() в стандартной библиотеке C. Возможно, это просто упражнение?

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