чем отличается char** от char[][]?
От: Аноним  
Дата: 28.08.07 03:33
Оценка:
Это одно и тоже?

и есть код
char buff[10];
char **p = (char**)&buff;

cout << strtol("FF s", p, 16);
cout << *p;

он работает правильно, но я не совсем понимаю как всё работает, прокоментируйте плиз.
Re: чем отличается char** от char[][]?
От: igna Россия  
Дата: 28.08.07 06:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>он работает правильно, но я не совсем понимаю как всё работает, прокоментируйте плиз.


Тут buff вообще не нужен. Вот код, который работает также:

char **p;

cout << strtol("FF s", p, 16);
cout << *p;
Re: чем отличается char** от char[][]?
От: ansi  
Дата: 28.08.07 06:23
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Это одно и тоже?


А>и есть код

А>
А>char buff[10];
А>char **p = (char**)&buff;

А>cout << strtol("FF s", p, 16);
А>cout << *p;
А>

А>он работает правильно, но я не совсем понимаю как всё работает, прокоментируйте плиз.

char[][] — это единый непрерывный блок памяти, доступ к которому происходит по двум индексам по следующей формуле:

    j
  1 2 3
i 4 5 6
  7 8 9


char a[m][n];

&a[i][j] == &a[0][0] + i*n + j;

В памяти:
                    | a + i*n + j
. . . . . . 1 2 3 4 5 6 7 8 9 . . . . . .


char ** — это, если рассматривать с точки зрения массивов, массив указателей на непрерывные блоки памяти. Эти непрерывные блоки могут располагаться, в общем случае, где угодно.
char **a = new char *[m];

for (int i = 0; i < m; ++i)
{
   a[i] = new char[n];
}

Доступ:
&a[i][j] == *(a + i) + j;

В памяти:
      a[1]                      a[2]      a[0]
. . . 4 5 6 . . . . . . . . . . 7 8 9 . . 1 2 3 . . . . . . .
Re: чем отличается char** от char[][]?
От: Graf Alex Украина http://grafalex.oberon.kiev.ua
Дата: 28.08.07 13:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это одно и тоже?


А>и есть код

А>
А>char buff[10];
А>char **p = (char**)&buff;

А>cout << strtol("FF s", p, 16);
А>cout << *p;
А>

А>он работает правильно, но я не совсем понимаю как всё работает, прокоментируйте плиз.

У тебя тут 2 вопроса:
Первый задан в теме поста: чем отличается char** от char[][] — на него очень хорошо ответил ansi

второй собственно по коду... его то я и прокомментирую...

Суть в том, что strtol ВОЗВРАЩАЕТ указатель на первый непропарсеный символ в строке. В данном случае тебе вернут указатель на подстроку в твоей строке начинающуюся с пробела. Т.е. FF пропарсится и сконвертируется в число 256, на пробеле функция застопорится и вернет указатель на этот самый пробел...

Почему это указатель на указатель? Да потому, что в С (тот который не С++) нет ссылок. Функции strlen нужно возвращать 2 значения: пропарсеное число (оно возвращается как результат функции) и указатель на первый символ непропарсеной строки. Т.к. нет ссылок, тебе приходится передавать указатель на ячейку памяти, куда функция положит указатель на подстроку. Т.о. получается указатель на указатель.

Как уже заметили ничего общего с двумерным массивом тут нет. И как опять же заметили первые 2 строки лишние:
первая: буффер тебе тут не нужен — возвращаемый указатель будет указывать на кусок неименованой константной строки, которую ты явно передаешь первым параметром в strlen
вторая: поскольку p это возвращаемое значение его необязательно инициализировать. Достаточно только объявить

Типичные примеры использования функции и использования возвращаемого указателя:
1) собственно парсинг: запускаем функцию, функция парсит число, возвращает указатель на то, что находится после этого числа. Далее может парсится другой кусок входного текста, начиная с символа, на который указывает возвращаемый указатель
2) проверка правильности конвертации строки в число. Если сравнить этот указатель с указателем на строку + ее размер можно убедится, что строка проконвертировалась в число полностью. Как более простой вариант: разименовать этот указатель и убедится в том, что значение по этому указателю равно нулю (конец строки).
Между прочим использование этой функции это наиболее правильный вариант конвертации строки в число.

int stringToInt(const char * pStr, int &iRes)
{
    char * pEnd;

    if(*pStr == \0)
        return STRING_TO_INT_EMPTY;

    iRes = strtol(pStr, &pEnd, 10);

    if(*pEnd != \0)
        return STRING_TO_INT_ERROR;

    return STRING_TO_INT_SUCCESS;
}
Re[2]: чем отличается char** от char[][]?
От: MasterZiv СССР  
Дата: 29.08.07 10:19
Оценка:
ansi пишет:
> char ** — это, если рассматривать с точки зрения массивов, массив
> указателей на непрерывные блоки памяти. Эти непрерывные блоки могут
> располагаться, в общем случае, где угодно.

Никаких если.
char ** — это указатель на указатель на char. При чем здесь массивы ?
Т.е. "неприрывных блоков" может вообще не быть.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: чем отличается char** от char[][]?
От: SpeCT Россия  
Дата: 29.08.07 16:01
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>char ** — это указатель на указатель на char. При чем здесь массивы ?

MZ>Т.е. "неприрывных блоков" может вообще не быть.

char * — указатель на непрерывный блок памяти (из чаров, если можно так выразиться)
char ** — указатель на непрерывный блок памяти (из указателей на непрерывный блок памяти "из чаров"")
Re[4]: чем отличается char** от char[][]?
От: MasterZiv СССР  
Дата: 30.08.07 09:06
Оценка:
SpeCT пишет:
> MZ>char ** — это указатель на указатель на char. При чем здесь массивы ?
> MZ>Т.е. "неприрывных блоков" может вообще не быть.
>
> char * — указатель на непрерывный блок памяти (из чаров, если можно так
> выразиться)

Проснись, char * — указатель на один объект типа char, где сказано,
что вокруг него находятся еще другие такие же ?

> char ** — указатель на непрерывный блок памяти (из указателей на

> непрерывный блок памяти "из чаров"")

Соответственно то же самое — логика неверна.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.