Форум программистов, компьютерный форум CyberForum.ru

Различия между двумя циклами - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 15:31     Различия между двумя циклами #1
объясните различия между двумя следующими циклами while

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
using namespace std;
 
int main ()
{
    const char *cp="hello";
    int cnt=0;
 
    while(cp){++cnt; ++cp;}
    while(*cp){++cnt; ++cp;}
 
    system("pause");
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
19.06.2011, 15:34     Различия между двумя циклами #2
Цитата Сообщение от Olejeg85 Посмотреть сообщение
while(cp){++cnt; ++cp;}
Это же вечный цикл.
Будет работать, пока указатель на что-то указывает(не равен нулю)
Цитата Сообщение от Olejeg85 Посмотреть сообщение
while(*cp){++cnt; ++cp;}
Будет сдвигать указатель и увеличивать cnt, пока указатель не указывает на конец строки. Фактически получится длина строки
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 15:48  [ТС]     Различия между двумя циклами #3
Цитата Сообщение от diagon Посмотреть сообщение
Это же вечный цикл.
Будет работать, пока указатель на что-то указывает(не равен нулю)

Будет сдвигать указатель и увеличивать cnt, пока указатель не указывает на конец строки. Фактически получится длина строки

а по поводу этого цикла можно подробнее? while(cp){++cnt; ++cp;}
почему он бесконечный получается? если там в конце тоже итератор стоит и по идее как только до конца строки дойдет и встретит 0 то тоже должен перестать работать, единственный отличай я понял что в первом варианте он в условии имеет в качестве значения адрес, а во втором случае имеет ссылку на первый элемент массива или я не правильно понял записи?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
19.06.2011, 15:51     Различия между двумя циклами #4
Цитата Сообщение от Olejeg85 Посмотреть сообщение
а по поводу этого цикла можно подробнее? while(cp){++cnt; ++cp;}
почему он бесконечный получается? если там в конце тоже итератор стоит и по идее как только до конца строки дойдет и встретит 0 то тоже должен перестать работать, единственный отличай я понял что в первом варианте он в условии имеет в качестве значения адрес, а во втором случае имеет ссылку на первый элемент массива или я не правильно понял записи?
Потому что даже после выхода за границы массива он будет на что-то указывать, т.е. не будет равен нулю, поэтому условие должно выполнятся всегда. При этом ему без разницы, на что он указывает, т.к. разыменование не используется.
А вот во втором случае используется разыменование, т.е. проверяется не сам указатель, а то, на что он указывает.
И никакого итератора в конце нету...
Хотя бы потому, что итераторы используются в контейнерах=\
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 15:55  [ТС]     Различия между двумя циклами #5
ну и еще такой вопрос

arr[]; - указатель на первый элемент массива
*parr=arr; - указатель на первый элемент массива

разницы я так понимаю нет?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
19.06.2011, 16:01     Различия между двумя циклами #6
Цитата Сообщение от Olejeg85 Посмотреть сообщение
ну и еще такой вопрос

arr[]; - указатель на первый элемент массива
*parr=arr; - указатель на первый элемент массива

разницы я так понимаю нет?
Не понял вопроса...
arr[] это не совсем указатель...
C
1
char arr[]="qwerty";
Это означает, что размер массива компилятор определит сам(в данном случае 7, под слово и нуль-символ)
C
1
arr[0]
Это доступ к нулевому элементу массива, и, если вы имели в виду его, то да, разницы в общем-то нету.
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 16:04  [ТС]     Различия между двумя циклами #7
из этой строки char arr[]="qwerty"; следует, что arr это тоже указатель на первый элемент массива?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
19.06.2011, 16:08     Различия между двумя циклами #8
Опять недопонял...

arr = это указатель на "qwerty"
Если его разыменовать(*arr), то получим первый элемент
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 16:11  [ТС]     Различия между двумя циклами #9
Цитата Сообщение от diagon Посмотреть сообщение
Опять недопонял...

arr = это указатель на "qwerty"
а вот *arr - это указатель на первый элемент.
но если *parr=arr; присвается не "qwerty", а указатель на первый элемент...
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
19.06.2011, 16:15     Различия между двумя циклами #10
Присваивается также указатель на "qwerty"
И если разыменовать, то он опять же будет указывать на первый элемент.
C
1
2
3
char * p = a;//указывает на q
++p; //теперь р указывает на w
++p;//теперь на e
Можете проверить
C++
1
2
3
char a[]="qwerty"; 
char * p = a;
cout << p;
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
19.06.2011, 16:33     Различия между двумя циклами #11
Если сравнивать указатель в цикле то нужен последний адрес-элемента массива или буфера, чтобы завершить цикл до идентичности адресов памяти, такой приём в основном применяют для
написания кросс-процессорных алгоритмов типа STL.

C++
1
2
3
4
5
6
7
8
 const char *cp="hello";
 int cnt=0;
 
const char*  end = cp + strlen(cp);
while( cp != end ) {
       *cp++;
         cnt++;
}
---

в этом случае сравнивается данные из массива или буфера в нашем случае строки заканчиваются '\0' - до его окончания цикл будет завершён.
C++
1
while(*cp){++cnt; ++cp;}
Olejeg85
13 / 10 / 0
Регистрация: 27.03.2011
Сообщений: 164
19.06.2011, 16:38  [ТС]     Различия между двумя циклами #12
вот два способа написания
C++
1
2
3
    char arr[]="hello, world";
//или
char *ptr="hello, world";
я разницы между ними особой не вижу, что в первом случае, что во втором, действия можно над ними в обоих случаях проводить одинаковые

вообще разница в использовании есть? или тут уже кому как больше нравится?
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
19.06.2011, 19:42     Различия между двумя циклами #13
Цитата Сообщение от Olejeg85 Посмотреть сообщение
вот два способа написания
C++
1
2
3
    char arr[]="hello, world";
//или
char *ptr="hello, world";
я разницы между ними особой не вижу, что в первом случае, что во втором, действия можно над ними в обоих случаях проводить одинаковые

вообще разница в использовании есть? или тут уже кому как больше нравится?
Разница есть. Даже две разницы
Первое отличие заключается в том, что первая строчка создаёт массив, элементы которого можно менять, а вторая указывает на константную строку, менять которую (в общем случае) недопустимо. Поэтому вторую строку надо бы записывать так:
C++
1
char const *ptr="hello, world";
Второе отличие — между именем массива и указателем на массив. Проявляется оно в уникальном свойстве. Для имени массива верно:
C
1
&arr[0] == (char*)&arr
А для указателя
C
1
&ptr[0] != (char*)&ptr
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
20.06.2011, 08:57     Различия между двумя циклами #14
Цитата Сообщение от xAtom
C++
1
const char*  end = cp + strlen(cp);
зачем использовать strlen(), если она точно так же реагирует на нуль-символ в конце

C++
1
2
3
4
5
6
7
8
const char *cp="hello";
 int cnt=0;
 
const char*  end = cp + strlen(cp);
while( cp != end ) {
       *cp++;
         cnt++;
}
C++
1
2
3
4
5
    const char *cp = "hello";
    int cnt = 0;
 
    while (*cp++)
       cnt++;
C++
1
2
    const char *cp = "hello";
    int cnt = strlen(cp);
tylix
68 / 55 / 6
Регистрация: 10.06.2011
Сообщений: 149
20.06.2011, 12:08     Различия между двумя циклами #15
Цитата Сообщение от accept Посмотреть сообщение
зачем использовать strlen(), если она точно так же реагирует на нуль-символ в конце
Это вопрос??

Не по теме:

У меня встречный: Зачем писАть свою функцию strlen(), если такая уже есть?
зачем мне вставлять два цикла вместо
if (strlen(a) > strlen(b)) ?



ПС accept сорри, я так понял ты это и хотел кому-то показать )
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.06.2011, 12:57     Различия между двумя циклами #16
Цитата Сообщение от Olejeg85 Посмотреть сообщение
если там в конце тоже итератор стоит и по идее как только до конца строки дойдет и встретит 0
Нолю равен символ, а не указаетль на него, условием же продолжения является именно ненулевой указатель.

Добавлено через 3 минуты
Цитата Сообщение от diagon Посмотреть сообщение
arr[] это не совсем указатель...
C++
1
int arr[]={2123,231,23,3423}; //массив, реализуемый через указатель, далее име arr везде будет обозначать константый неразыменованный указатель на переменную
Добавлено через 4 минуты
Цитата Сообщение от Olejeg85 Посмотреть сообщение
arr[]; - указатель на первый элемент массива *parr=arr; - указатель на первый элемент массива разницы я так понимаю нет?
Разницы между копированием укзателя из arr в явный указатель и его непосредственным использованием нет за исключением циклов, перебирающих указатель:
C++
1
2
int arr[]=...;
for(; arr</*Не счем сравниваить*/; ++arr /*Не допустимо, так как указаетль то константный*/)
C++
1
2
3
int arr[n]=...;
int *p;
for(p=arr; p<arr+n; ++p)// А здесь всё в порядке
Добавлено через 5 минут
Цитата Сообщение от diagon Посмотреть сообщение
arr = это указатель на "qwerty" Если его разыменовать(*arr), то получим первый элемент
Вообще то и arr указывает на первый символ, различие между указателем на массив (не путать с указателем на указатель на массвив) и на его нулевой элемент лишь в использовании: по указателю на массив и индексу элмента вычисляется указатель на этот элемент, а указатель на нелевой элмент используется непосредственно для его адресации, но указатель на произвольный элемент вычисляется простым сложением указателя на нулевой элемент с произведением размера и индекса элемента, а использование одного и того же указателя в обеих опостасях не требует даже приведения типа.

Добавлено через 7 минут
Цитата Сообщение от grizlik78 Посмотреть сообщение
&arr[0] == (char*)&arr
&arr имеет тип char ** и имеет значение указателя на arr, (char *)приводит к char*, arrх[0] имеет тип char. Хотя, тест показывает, что равенство истинно, но абсолютно не понятно, с какого перпугу так должно быть.

Добавлено через 6 минут
А вот с точки зрения sizeof статичесткий массив и указатель на его элемент - не одно и то же. Для массива sizeof вёрнёт размер в байтах массива, а для указателя - самого указателя.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
20.06.2011, 13:12     Различия между двумя циклами #17
Цитата Сообщение от taras atavin Посмотреть сообщение
но абсолютно не понятно, с какого перепугу так должно быть.
Ну вот есть такая особенность.

Цитата Сообщение от taras atavin Посмотреть сообщение
А вот с точки зрения sizeof статичесткий массив и указатель на его элемент - не одно и то же. Для массива sizeof вёрнёт размер в байтах массива, а для указателя - самого указателя.
Да, разумеется. Я должен был об этом вспомнить!

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
&arr имеет тип char **
Не совсем так. &arr имеет тип указателя на массив, который без вопросов автоматически может приводиться к двойному указателю char**
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.06.2011, 13:12     Различия между двумя циклами #18
Вообще статический массив нифига не указатель, а некая сущность, с которой ассоциированы размер всего массива и указатель на его нулевой элемент.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
21.06.2011, 01:25     Различия между двумя циклами #19
Цитата Сообщение от tylix Посмотреть сообщение
Это вопрос??

Не по теме:

У меня встречный: Зачем писАть свою функцию strlen(), если такая уже есть?
зачем мне вставлять два цикла вместо
if (strlen(a) > strlen(b)) ?



ПС accept сорри, я так понял ты это и хотел кому-то показать )
часто бывают задания учебные, где функции стандартной библиотеки пишутся своими руками
исходный код в первом сообщении как раз демонстрирует, что там подсчитывается длина строки
xAtom в сообщении написал избыточный код, а я продемонстрировал, как его можно сократить в контексте исходного задания, и как его можно сократить вообще

не смотри, что там указатель выходит за край, даже за нуль-символ, это можно, устанавливать указатель за последний элемент массива
и даже в таком случае от него можно отнять (cnt + 1), возвратившись к исходной строке, не теряя её
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2011, 09:25     Различия между двумя циклами
Еще ссылки по теме:

Расстояние между двумя множествами точек - это расстояние между наиболее близко расположенными точками этих C++
C++ Различия в скоростях между curl и libcurl
Различия между scanf("%s") и gets() C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.06.2011, 09:25     Различия между двумя циклами #20
Цитата Сообщение от tylix Посмотреть сообщение
Не по теме: У меня встречный: Зачем писАть свою функцию strlen(), если такая уже есть?
А откуда тебе известно, что текущая её версия оптимальна? Иначе же актуальна разработка её новой версии. Новичок врядли сможет сделать лучше, чем стандартные функции уже написаны, но если их доработка актуальна, то кто же будет профессионально этим заниматься. Может это когданибудь будешь ты? Или вдруг тебе потом понадобится не стандратный динамический контейнер, измеряющий, но не хранящий свой размер? Какую нибудь новую корягу изобретёшь с функцией-членом числа узлов? Или строку не стандартную? Или будешь делать числовой тип переменной разрядности и тебе там понадобится функция-член, измеряющая разрядность?
Yandex
Объявления
21.06.2011, 09:25     Различия между двумя циклами
Ответ Создать тему
Опции темы

Текущее время: 11:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru