2013-10-14 2 views
1

Я новичок в C++ и столкнулся с проблемой, о которой я не знаю, что делать. Я делал несколько примеров в книге, когда натолкнулся на следующий фрагмент кода.Array index in for loop

for(int i=0;string[i];i++){ 
    cout<<string[i]; 
} 

Здесь вместо булева для второго аргумента лица данного массива index.Based по этому методу я побежал следующий кусок кода, но это не сработало.

char string[50] ="This is a test!"; 

for(int i=sizeof(string)-1;string[i];i--){ 
    cout<<string[i]; 
} 

cout<<"\n"; 

Я отлажена это и 'строка [я] имеет значение 0. Таким образом, мои вопросы,

  1. Зачем использовать индекс массива вместо булево (это ОК ?).
  2. Почему моя вторая часть кода не работала.

Заранее спасибо.

+1

Строковые литералы (и струнных general) end in a 0. – chris

ответ

6

Логический тест string[i] на самом деле просто проверяет, существует ли нулевой символ ('\0'). Все строки в C заканчиваются нулевым символом, и поэтому это работает для форвардной итерации через строку. Но нет, если вы идете в обратном направлении. Вместо этого следует проверить, что i больше или равно нулю.

Кроме того, sizeof(string) возвращает размер типа данных (50 байтов или, возможно, больше), а не длину содержащейся в нем строки. Чтобы получить длину строки, используйте strlen:

for(int i = strlen(string) - 1; i >= 0; i--) { 
    cout << string[i]; 
} 

Я бы посоветовал против вызова переменных string, так как это тип данных в стандартной библиотеке, и запутанная для программистов C++, если вы используете его в качестве имени переменного. Тем более, что люди довольно часто импортируют все пространство имен std и ссылаются на класс строк как string.

Это как вызов всех ваших числовых значений «целое число». Выполнение этого на самом деле не говорит программисту, для чего он используется, только то, что он есть. Пожалуйста, используйте более описательные имена переменных =)

+1

small thing: string array not string class – Cramer

+0

Я согласен с именами переменных, но поскольку это был тест, я не обращал внимания на имена. В любом случае, когда я использую strlen, массив продолжается для -значений, любая идея о том, почему? – Madz

+1

Я не совсем понимаю, что вы там сказали, @Madz - вы имеете в виду, что 'i' принимает отрицательные значения? Возможно, отредактируйте свой вопрос и покажите какой-нибудь результат, который показывает, что вы видите, вместе с кодом для воспроизведения. – paddy

1

В приведенном выше цикле символ используется вместо bool в качестве второго аргумента. В этом случае ненулевые значения считаются «истинными», а нулевое значение считается «ложным».

Во втором коде цикл не выполняется, поскольку строка [sizeof (string) -1] равна нулю и оценивается как «false».

Если вы используете следующим образом, ваш код будет работать

for(int i=0;string[i];i++){ 
1

Поскольку это C++, а не C, вы могли бы быть лучше, используя встроенный класс строк, а не использовать массивы символов.

Вот один из способов распечатать реверс вашей строки посимвольно:

#include <iterator> 
... 
typedef std::reverse_iterator<std::string::iterator> rev_iter; 

string str("This is a freaking test!"); 
for(rev_iter it (str.end()); it != rev_iter(str.begin()); ++it) 
    std::cout << *it; 
std::cout << endl; 

И еще один (но это изменяет строку):

#include <algorithm> 
... 
string str("This is a freaking test!"); 
reverse(str.begin(), str.end()); 
cout << str << endl;