Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разница между [] и * 
:(
    Опции темы
Romikgy
Дата 27.9.2006, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(sergejzr @  27.9.2006,  12:05 Найти цитируемый пост)
это не хороший совет.

может , но рабочий smile
Цитата(sergejzr @  27.9.2006,  12:05 Найти цитируемый пост)
Потому что char * и char[] это структурно уже не одно и тоже.

объясни плз в чем разница!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
sergejzr
Дата 27.9.2006, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Цитата(Romikgy @  27.9.2006,  11:30 Найти цитируемый пост)
может , но рабочий smile

Рабочий он, но только с одномерным массивом, потому что реализачия действительно на большинстве компилеров почти одинакова.

Цитата(Romikgy @  27.9.2006,  11:30 Найти цитируемый пост)
объясни плз в чем разница! 

На примере многомерного попробую обьяснить.
Как мы знаем, многомерный массив после аллокации и инициализации будет выглядеть так:

char **x=new char *[5];
for(int i=0;i<5;i++)
{
x[i]=randomstring();//предположим, эта функция возвращает char* 
}

[0]->['3456345']
[1]->['1234']
[2]->['etzertz']
[3]->['78904567']
[4]->['7890789']

А если определить
char y[5][10];

То выделен на весь массив будет один участок памяти. (одномерный массив)
[0,1,2,3,4,5,6,..50]

при этом если обращаемся к динамическому х х[2][3], то берётся третья буква второго элемента, а если обращаемся к "статическому" y y[2][3], то index элемента в массиве будет вырешан. например 2*5+3;

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

Поэтому после "преобразования" одного типа массива в другой, ошибки при доступе неизбежны. char **c=(char**)y; Такого например уже хороший компилер сделать не даст, но компилер всегда можно обмануть (как ты и сделал).

С одномерными, как я уже сказал, проще, но лучше не привыкать к таким вещам.



--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Romikgy
Дата 27.9.2006, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



sergejzr, я ниче не понял smile
имхо 
Цитата(sergejzr @  27.9.2006,  12:53 Найти цитируемый пост)
x[i]=randomstring();//предположим, эта функция возвращает char* 

это не правомерно т.к. 
Цитата(sergejzr @  27.9.2006,  12:53 Найти цитируемый пост)
char *x=new char [5];

это дин. массив чаров, а ты туда указатель на чар  smile 
Цитата(sergejzr @  27.9.2006,  12:53 Найти цитируемый пост)
но компилер всегда можно обмануть (как ты и сделал).

имхо я не обманывал , а преобразовал к нужному типу.
Цитата(sergejzr @  27.9.2006,  12:53 Найти цитируемый пост)
при этом если обращаемся к динамическому х х[2][3], то берётся третья буква второго элемента, а если обращаемся к "статическому" y y[2][3], то index элемента в массиве будет вырешан. например 2*5+3;

этого я вообще не понял, smile
имхо все массивы в памяти преобразуются в одномерный массив, а уж динамика это или статика имхо для проги все равно , разница где это размещается, имхо


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Romikgy
Дата 27.9.2006, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(sergejzr @  27.9.2006,  13:58 Найти цитируемый пост)
указательна массив и массив - разные вещи.

да не спорю 
char s[]
и 
char *s[] 
это разные вещи, но это понять не могу
Цитата(sergejzr @  27.9.2006,  13:58 Найти цитируемый пост)
Один раз у тебя массив элементов char[][] а другой раз массив из указателей на другие массивы char** 

мне не понятна в чем разница между char** и char [][] я имею ввиду для дальнейшего использования , ане для инициализации?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
sergejzr
Дата 27.9.2006, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Сейчас, разделю темку, а то оффтоп пошёл smile

ПС:
Ну представь, функция у тебя

void test(char**x){}

а ты ей y[][] передал smile


Набросал примерчик. Смотри то, что выделено тире smile

Код

//Это всё необходимо для компиляции. К самому вопросу мало относится 
//Имтересная часть выделена тире
#include <cstdlib>
#include <iostream>

using namespace std;
#define dim1 2
#define dim2 3
char* randomstring(int cnt);

int main(int argc, char *argv[])
{
   //Вот два массива, которые мы и будем сравнивать между собой
    char y[dim1][dim2];
    char **x;
    
//Проинициализируем их одинаковыми значениями
    x=new char *[dim1];
    for(int i=0;i<dim1;i++)
    {
     x[i]=randomstring(dim2);
    }

    for(int i=0;i<dim1;i++)
    {
     for(int z=0;z<dim2;z++)
     y[i][z]=x[i][z];
    }


//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------   
    //Остюда собственно начинается самое интересное...
    for(int i=0;i<dim1;i++)
    {
     for(int z=0;z<dim2;z++)
     printf("x[%i][%i]=%c\t\t y[%i][%i]=%c\n",i,z,x[i][z],i,z,y[i][z]);
     //Как видим значения в обеих массивах совпадают до байта. Операторы доступа также идентичны на первый взгляд, оба - []
     //И хотя нам кажется, что скобки в обоих случаях работают одинакого, это не так
     //Это нам докажет следующий цикл
    }
    
    
    char **tricky; //Это будет вспомогательный указатель

    tricky=(char **)y; //О-о! Тут мы обманываем не только компилятор, но и сами себя, как выяснится вскоре.
    
    for(int i=0;i<dim1;i++)
    {
     for(int z=0;z<dim2;z++)
     printf("tricky[%i][%i]=%c\n",i,z,tricky[i][z]);
     //Здесь прога вылетит со скрипом.
     //Всё дело в том, что оператор[] по разному работает для статических и динамических массивов
    }
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 



//Дальше можно не рассматривать.
return 0;

}
char* randomstring(int cnt)
{
char *ret=new char[cnt];
for(int i=0;i<cnt;i++)
{
        ret[i]='0'+rand()%70;
}
  return ret;    
}


Так что char*,char**, и char[][] это всё разные вещи и преображать одно к другому можно лишь точно понимая, что ты делаешь.


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Romikgy
Дата 28.9.2006, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(sergejzr @  27.9.2006,  14:15 Найти цитируемый пост)
Сейчас, разделю темку, а то оффтоп пошёл 

вот я ее и посеял smile
Цитата(sergejzr @  27.9.2006,  14:15 Найти цитируемый пост)
tricky=(char **)y; //О-о! Тут мы обманываем не только компилятор, но и сами себя, как выяснится вскоре.
    
    for(int i=0;i<dim1;i++)
    {
     for(int z=0;z<dim2;z++)
     printf("tricky[%i][%i]=%c\n",i,z,tricky[i][z]);
     //Здесь прога вылетит со скрипом.
     //Всё дело в том, что оператор[] по разному работает для статических и динамических массивов
    }

имхо не корректное преобразование т.к. при обращении tricky[i][z] мы должны знать размерность массива , а при передаче tricky=(char **)y; мы по минимуму теряем 1  размерность , и я такого нигде не видел,
везде где идет передача массива более 1 размерности , тогда делают типа такого 
 tricky[][5] тогда понятно будет проге что у нас массив какая то куча строк и 5 столбцов (ну или наоборот)
имхо приобразование как я делал , никакого обмана не несет , а твой пример серьйозно обманывает и компилятор и себя , плюс приводит к неработоспособности проги!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
MAKCim
Дата 28.9.2006, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

мне не понятна в чем разница между char** и char [][] я имею ввиду для дальнейшего использования , ане для инициализации? 

char** и char[][] - разные типы - в этом вся разница, другое дело, что их использование тесно переплетается


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Romikgy
Дата 28.9.2006, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(MAKCim @  28.9.2006,  12:22 Найти цитируемый пост)
char** и char[][] - разные типы 


MAKCim, давай без пространственных фраз в чем они разные?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
sergejzr
Дата 28.9.2006, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Цитата(Romikgy @  28.9.2006,  10:53 Найти цитируемый пост)
имхо приобразование как я делал , никакого обмана не несет

Ты там по живому режешь и просто везёт, что в данном случае реализация char* и char[] совпали. 
А что если компилятор из char[] вообще свой класс делает у которого оператор[] переложен? Стандарт такое позволяет делать.


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
MAKCim
Дата 28.9.2006, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

MAKCim, давай без пространственных фраз в чем они разные? 

что значит в чем?
char** - двойной указатель на char - указывает на указатель, который содержит адрес char
char[][] - тип двумерного массива - нельзя неявно преобразовать к char**
может еще указатель и массив одно и то же?

Это сообщение отредактировал(а) MAKCim - 28.9.2006, 13:41


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Romikgy
Дата 28.9.2006, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 8
Всего: 146



Цитата(sergejzr @  28.9.2006,  12:33 Найти цитируемый пост)
класс делает у которого оператор[] переложен?

не понял smile
Цитата(MAKCim @  28.9.2006,  12:40 Найти цитируемый пост)
еще указатель и массив одно и то же?

объясни в чем разница между массивами и указателями в си?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
EvgenZ
Дата 28.9.2006, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: 1
Всего: 11



А я думал, что имя массива и есть указатель... И что кому как удобнее тот так и делает (* или [] )


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
sergejzr
Дата 28.9.2006, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Цитата(Romikgy @  28.9.2006,  11:29 Найти цитируемый пост)
давай без пространственных фраз в чем они разные? 

Я же специально во втором посте этой теме это попытался расжевать smile

char **

[0]->['3456345']
[1]->['1234']
[2]->['etzertz']
[3]->['78904567']
[4]->['7890789']

Для реализации массива 5,10 необходимо 5+5*10=55 байт 5 байт указателей и 50 байт содержимого причём содержимое может частями находится в любом месте RAM.

А у char[5][10] всего 50 байт и все лежат массивом подряд.

Добавлено @ 13:55 
Цитата(Romikgy @  28.9.2006,  11:46 Найти цитируемый пост)
объясни в чем разница между массивами и указателями в си? 

Массив - структурированный участок памяти. Указатель - ячейка памяти.

Цитата(EvgenZ @  28.9.2006,  11:49 Найти цитируемый пост)
А я думал, что имя массива и есть указатель... И что кому как удобнее тот так и делает (* или [] ) 

Массив никуда "указывать" не может. В отличии от указателя, который как раз на массив может также указывать.


Я не могу больше обьяснять. Просто не знаю как понятнее сказать..

Цитата(Romikgy @  28.9.2006,  11:46 Найти цитируемый пост)
не понял smile

Знаешь такой класс Vector? В нём тоже есть оператор [] и работает как массив, но Vector это КЛАСС и преобразовать его в массив путём обьявления - приведёт к неопределённым последствиям.



--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
EvgenZ
Дата 28.9.2006, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


Профиль
Группа: Участник
Сообщений: 407
Регистрация: 3.8.2006

Репутация: 1
Всего: 11



Мне в голову пригшла мысль, т.е. если у меня есть массив [][] , то я могу обращаться к нему с помощью указателей ** , а если он представлен у меня **, то я немогу использовать [][]. Правильно?


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
sergejzr
Дата 28.9.2006, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Это разные вещи и нельзя ни того, ни другого. В примере кода я показал, как из char** правильно сделать char[][] - копированием при инициализации. И как неправильно - преобразованием (char**);


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0626 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.