Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: непонятность с указателями
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Метценгерштейн
char *initResult = InitDevice();
if ( initResult != "SUCCESS")
{
return initResult;
}

задавал вопрос на телесистемах, ничего вразумительного не получил в ответ

здесь что происходит? адрес значения ф-ии присваиваю указателю *initResult ?
kamil_yaminov
строки нельзя просто так сравнить, надо использовать что-то типа strcmp, ежели не вру
Метценгерштейн
хорошо, если это не строки, а числа, например

int *initResult = InitDevice();
if ( initResult != 123)
{
return initResult;
}

вопрос тот же
kamil_yaminov
Возвращаемое функцией значение, помещается в память. Ежели адрес в памяти, куда записалось возвращаемое значение, не равен 123, то возвращаем адрес
Andron_
в initResult записывается некий адрес *хз ваще, че за адрес, мы не знаем*, возвращенный функцией. Если адрес не равен 123, возвращаем адрес.
Метценгерштейн
а правильно было бы сравнивать два числа так:
int *initResult = InitDevice();
if ( *initResult != 123)
{
return initResult;
}

теперь, если результат по адресу на кот. указывает указатель не равен 123 ... так ?


сравнение строк теперь корректно? т.е. если совпадают, то результат =0 ?

char *initResult = InitDevice();

if ( strcmp( initResult, "SUCCESS") == 0)
Andron_
Цитата
теперь, если результат по адресу на кот. указывает указатель не равен 123 ... так ?

ну типа того...

только возникает ряд вопросов по поводу распределения памяти в такой конструкции.... ну это так... к делу не относится.
Метценгерштейн
спасибо, мне идею надо было понять с указателями и strcmp.
Палыч
Цитата(Метценгерштейн @ May 11 2010, 18:32) *
char *initResult = InitDevice();
.....
здесь что происходит? адрес значения ф-ии присваиваю указателю *initResult ?

Вызывается функция без параметровInitDevice(), которая возвращает указатель на char. Возвращаемое значение (адрес char) присваивается initResult для последующего анализа. Если возвращенный адрес не совпадает с неким адресом, то этот адрес и возвращается приведенным фрагментом функции... Зачем это таким образом сделано - очень большой вопрос!
Dima_G
Мне кажется, проще объяснить так

Код
const char* GetStrReslut()
{
  if (все плохо)
    return "FAILED";
  else
    return "SUCCESS";
}
* * *
const char* pcResult_ = GetStrReslut();
if (!strcmp(pcResult_, "SUCCESS"))
{
  // Function return success
}
sigmaN
Цитата
здесь что происходит? адрес значения ф-ии присваиваю указателю *initResult ?
Объясняю. Переменная указатель всегда хранит АДРЕС в памяти(просто число).
Если вам нужно сравнить адрес, то тогда нужно писать
Код
if ( initResult != 123 )
Если указатель типизированный, то к нему можно применить операцию разыменование указателя. В Си это делается путем добавления звездочки перед именем указателя.
Т.е. если
Код
int *initResult = InitDevice();
то
Код
if( *initResult != 123 )
позволит сравнить уже не адрес, а ТО, ЧТО ЛЕЖИТ ПО ЭТОМУ АДРЕСУ В ПАМЯТИ.
Также можно и переслать значение в этот адрес.
Код
*initResult = 123;


Далее, что происходит, когда вы пишите
Код
char *msg = "message1";
На самом деле компилятор выделяет память под строку "message1" и инициализирует её этим значением "message1\0". Далее, в переменную msg поступает АДРЕС ячейки памяти в которой лежит буква m(первый символ строки).

Так почему же нельзя сравнивать строки просто в if? именно потому, что строка в си - это просто символы, пока не встретится 0.
Что происходит, когда мы пишем
Код
char *initResult = InitDevice();
if ( initResult != "SUCCESS")
а происходит по сути сравнение указателей. Компилятор берет наш "SUCCESS" и, как я уже говорил, ложит в память. Поскольку первый операнд сравнения есть указатель initResult, то и второй операнд тоже будет указателем. Указателем на первый символ('S').
А теперь представим себе, что функция сформировала в неком буфере с адресом 0x00f1 строку SUCCESS и вернула нам указатель на этот буфер(0x00f1) в нашем if() мы использовали "SUCCESS" в надежде, что компилятор сравнит строки, а на самом деле он сравнит указатели и они не могут быть равны, т.к. для "SUCCESS" компилятор выделил отдельно память, а функция использовала некий буфер и к примеру приняла туже строку "SUCCESS" с порта, но адреса точно не сойдутся - это разные области памяти, хоть и содержащие одинаковые данные. И очень обидно, что результат сравнения будет == 0 sad.gif

Что же делает strcmp()? А она берет первый символ одной строки и первый символ другой, сравнивает их, если они равны - переходит к следующему. И так пока не наткнется на конец одной из строк или на различие. Т.е. strcmp() сравнивает именно значения находящиеся по переданным ей указателям. strcmp() какраз использует разыменование указателей.

Да, кстати, указатели можно складывать, вычитать, умножать и делить. При этом мы делаем все эти операции с адресом, хранящимся в указателе. Так, например, можно "перенацелить" указатель с первого символа в строке, на второй. В общем то указатель можно сделать даже "из воздуха".
Код
unsigned int address = 0x001f; //адрес в памяти
unsigned int *ptr = (unsigned int *)address;
или даже так
Код
unsigned int *ptr = (unsigned int *)0x001f;


В общем тут надо бы почитать теорию )))
Dima_G
Цитата(sigmaN @ May 12 2010, 10:50) *
Да, кстати, указатели можно складывать, вычитать, умножать и делить.


07.gif
sigmaN
Пардон, немножко переборщил. ))

Их можно только вычитать.
К указателю можно прибавить целое.
Можно также отнять целое.
mdmitry
Может быть
Код
char *initResult = InitDevice();

следует рассматривать как некий аналог функции
Код
malloc
и аналогичных, но возвращающей указатель на char? В этом случае необходима традиционная проверка на NULL для указателя.
theBMV
Товарисчи, а ИМХО, отработав, все локальные переменные функции освобождаются, поэтому присвоение адреса локальной переменной функции, которая завершилась, ни разу не корректно. Эта память свободна, и при первой возможности ее займет какая-нибудь новая переменная.
Про strcmp уже молчу...
rezident
Цитата(theBMV @ May 20 2010, 13:17) *
Товарисчи, а ИМХО, отработав, все локальные переменные функции освобождаются, поэтому присвоение адреса локальной переменной функции, которая завершилась, ни разу не корректно.
Локальные переменные, используемые внутри функции , - да, освобождаются, но в данном случае указатель на функцию является результатом работы этой функции и поэтому он сохраняется для возврата его (результата) в вызывающую функцию. Только после этого (после передачи в вызывающую функцию) занимаемая им память может освободиться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.