реклама на сайте
подробности

 
 
> непонятность с указателями
Метценгерштейн
сообщение May 11 2010, 14:32
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



char *initResult = InitDevice();
if ( initResult != "SUCCESS")
{
return initResult;
}

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

здесь что происходит? адрес значения ф-ии присваиваю указателю *initResult ?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
kamil_yaminov
сообщение May 11 2010, 14:40
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 395
Регистрация: 15-02-08
Из: Новосибирск
Пользователь №: 35 064



строки нельзя просто так сравнить, надо использовать что-то типа strcmp, ежели не вру
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение May 11 2010, 14:43
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



хорошо, если это не строки, а числа, например

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

вопрос тот же

Сообщение отредактировал Метценгерштейн - May 11 2010, 14:43
Go to the top of the page
 
+Quote Post
kamil_yaminov
сообщение May 11 2010, 14:48
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 395
Регистрация: 15-02-08
Из: Новосибирск
Пользователь №: 35 064



Возвращаемое функцией значение, помещается в память. Ежели адрес в памяти, куда записалось возвращаемое значение, не равен 123, то возвращаем адрес
Go to the top of the page
 
+Quote Post
Andron_
сообщение May 11 2010, 14:53
Сообщение #5


.NET developer
***

Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532



в initResult записывается некий адрес *хз ваще, че за адрес, мы не знаем*, возвращенный функцией. Если адрес не равен 123, возвращаем адрес.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение May 11 2010, 14:55
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



а правильно было бы сравнивать два числа так:
int *initResult = InitDevice();
if ( *initResult != 123)
{
return initResult;
}

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


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

char *initResult = InitDevice();

if ( strcmp( initResult, "SUCCESS") == 0)
Go to the top of the page
 
+Quote Post
Andron_
сообщение May 11 2010, 14:58
Сообщение #7


.NET developer
***

Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532



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

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

только возникает ряд вопросов по поводу распределения памяти в такой конструкции.... ну это так... к делу не относится.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение May 11 2010, 15:01
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



спасибо, мне идею надо было понять с указателями и strcmp.
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 11 2010, 15:02
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



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

Вызывается функция без параметровInitDevice(), которая возвращает указатель на char. Возвращаемое значение (адрес char) присваивается initResult для последующего анализа. Если возвращенный адрес не совпадает с неким адресом, то этот адрес и возвращается приведенным фрагментом функции... Зачем это таким образом сделано - очень большой вопрос!
Go to the top of the page
 
+Quote Post
Dima_G
сообщение May 12 2010, 03:17
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Мне кажется, проще объяснить так

Код
const char* GetStrReslut()
{
  if (все плохо)
    return "FAILED";
  else
    return "SUCCESS";
}
* * *
const char* pcResult_ = GetStrReslut();
if (!strcmp(pcResult_, "SUCCESS"))
{
  // Function return success
}
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 12 2010, 03:50
Сообщение #11


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
здесь что происходит? адрес значения ф-ии присваиваю указателю *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;


В общем тут надо бы почитать теорию )))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Dima_G
сообщение May 12 2010, 04:04
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



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


07.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 12 2010, 04:47
Сообщение #13


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



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

Их можно только вычитать.
К указателю можно прибавить целое.
Можно также отнять целое.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
mdmitry
сообщение May 12 2010, 12:21
Сообщение #14


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Может быть
Код
char *initResult = InitDevice();

следует рассматривать как некий аналог функции
Код
malloc
и аналогичных, но возвращающей указатель на char? В этом случае необходима традиционная проверка на NULL для указателя.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
theBMV
сообщение May 20 2010, 07:17
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 14-10-08
Из: г. Королев
Пользователь №: 40 940



Товарисчи, а ИМХО, отработав, все локальные переменные функции освобождаются, поэтому присвоение адреса локальной переменной функции, которая завершилась, ни разу не корректно. Эта память свободна, и при первой возможности ее займет какая-нибудь новая переменная.
Про strcmp уже молчу...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.0151 секунд с 7
ELECTRONIX ©2004-2016