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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> указатели и функции - запутался 
:(
    Опции темы
ressac
Дата 2.5.2007, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



вот два примера, в первом выдаёт варнинги 

Цитата

In function `main':
 warning: passing arg 1 of `test' from incompatible pointer type
In function `test':
warning: assignment makes integer from pointer without a cast


а во втором нет.

в первом заначит я передаю адресс указателя в функцию и принимаю его как УКАЗАТЕЛЬ и там начинаю с ним работать

1
Код


#include <stdio.h>

void test (int*);

main()
{

    int *p;

    printf("\n 1. main dir: %i \n",p);

    test(&p);

    printf("\n 4. main dir: %i \n",p);

    printf("\n %i",*p);

    puts("\n\n");
    system("pause");

}

void test (int* p)
{

    printf("\n 2 test dir: %i \n",*p);

    *p=malloc(sizeof(int));
    scanf("%i",*p);

    printf("\n 3 test dir: %i \n",*p);

}



а во втором я передаю тоже адресс на указатель но принимаю его как указатель на укразатель...

2
Код


#include <stdio.h>

void test (int**);

main()
{

    int *p;

    printf("\n 1. main dir: %i \n",p);

    test(&p);

    printf("\n 4. main dir: %i \n",p);

    printf("\n %i",*p);

    puts("\n\n");
    system("pause");

}

void test (int* *p)
{

    printf("\n 2 test dir: %i \n",*p);

    *p=malloc(sizeof(int));
    scanf("%i",*p);

    printf("\n 3 test dir: %i \n",*p);

}



вообщем хелп :(
PM MAIL   Вверх
Xenon
Дата 2.5.2007, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Если ты передаешь адрес указателя, значит ты передаешь указатель на указатель, следовательно требуется тип int**

Это сообщение отредактировал(а) Xenon - 2.5.2007, 21:47


--------------------
user posted image  
PM MAIL   Вверх
Greeen
Дата 2.5.2007, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 7
Всего: 18



Вообще конечно трудно уловить логику проги, но все же
Код

#include <stdio.h>

void test (int* p)
{
    printf("\n2 test dir: %d\n", *p);
    p = malloc(sizeof(int));
    scanf("%d", p);
    printf("\n3 test dir: %d\n",*p);
}

int main()
{
    int *p;
    printf("\n1. main dir: %d\n", *p);
    test(p);
    printf("\n 4. main dir: %d\n", *p);
    printf("\n %d", *p);
    puts("\n\n");
    system("pause");
}



--------------------
Подпись больше не нужна
PM MAIL ICQ Skype   Вверх
ressac
Дата 2.5.2007, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Greeen, да нет там логики , просто изварашаюсь с указателями чтоб понять как они пашут, а это что ты запустил у меня компилится но прога вылетает с критической ошибкой...
PM MAIL   Вверх
Greeen
Дата 2.5.2007, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 7
Всего: 18



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

Добавлено через 1 минуту и 42 секунды
Код

#include <stdio.h>
void test(int* p)
{
    printf("\n2 test dir: %d\n", *p);
    p = malloc(sizeof(int));
    scanf("%d", p);
    printf("\n3 test dir: %d\n",*p);
}
int main()
{
    int p = 5;
    printf("\n1. main dir: %d\n", p);
    test(&p);
    printf("\n 4. main dir: %d\n", p);
    printf("\n %d", p);
    puts("\n\n");
    system("pause");
}

Вот так не вылетит.


--------------------
Подпись больше не нужна
PM MAIL ICQ Skype   Вверх
ressac
Дата 2.5.2007, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



не понятно то что почему должен ставить как УКАЗАТЕЛЬ НА УКАЗАТЕЛЬ во втором варианте ... чтоб не выходили варнинги
PM MAIL   Вверх
Greeen
Дата 2.5.2007, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 7
Всего: 18



Потому что:
1. У тебя p - указатель, а в функцию ты передаешь его адрес.
2. malloc возвращает указатель, а если у тебя int* p - то ты его разыменовываешь, и адрес записывается просто в p

Добавлено через 2 минуты и 49 секунд
Надеюсь не слишком непонятно объяснил  smile 


--------------------
Подпись больше не нужна
PM MAIL ICQ Skype   Вверх
ressac
Дата 2.5.2007, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Greeen, первый пунк понял smile а второй как то не очень smile


Цитата

а если у тебя int* p - то ты его разыменовываешь, и адрес записывается просто в p


что значит "разыменовываешь"  ?

malloc возвращает адресс на ячейку памяти скажем так, вот этот адресс я и сохраняю в "p" локальную

тойсть подставляю *p=malloc....


вообщем если можно поподробней smile

PM MAIL   Вверх
Xenon
Дата 2.5.2007, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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


--------------------
user posted image  
PM MAIL   Вверх
ressac
Дата 3.5.2007, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Xenon, серовно не понял,

дайте мне люди наверно хороший мануалчик по указателям для СИ а то толком ничего так и не пойму, или объясните ещё подробней почему надо указывать как указатель на указатил smile.

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

я надеюсь вы меня поняли smile))) и я себя тоже smile
PM MAIL   Вверх
Xenon
Дата 3.5.2007, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Ну так если 
Код

int var = 10;
int* pTr = &var; //Берем адрес переменной
std::cout << pTr //Адрес, по которому находится var
std::cout << *pTr //Снимаем косвеннсть - получаем доступ переменной, то это строчка, грубо говоря, аналогично std::cout << var
std::cout << &pTr //Адрес указателя, а не переменной
int** pTr2 = &pTr //Ты адрес указателя даешь указателю, поэтому получается указатель на указатель
std::cout << pTr2 //Адрес pTr
std::cout << *pTr2 //Сняли косвенность - получили доступ к pTr
std::cout << **pTr2 //получили доступ к var

То есть цепока получились [var] <- pTr <- pTr2

А читай вообще, Шилдта или Страуструпа. Это же азы.


Это сообщение отредактировал(а) Xenon - 3.5.2007, 00:20


--------------------
user posted image  
PM MAIL   Вверх
ressac
Дата 3.5.2007, 01:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Xenon, это я знаю, читал уже и видел и главное конечно что понимаю это

..но серовно  спасибо.

я просто не могу понять логику зачем делать указать на указатель когда просто можно сделать указатель на АДРЕС и всё, и почему компилятор ругается.. я не вижу смысл..

ведь если так подумать он то ведь компилит в конечном итоге всё это и всё правильно работает, значит ход мысли правильный... но вот компилятор почему - то говорит что это не правильно..

тоже самое у меня было когда я пытался переслать матрицу как указатель вот пример

Код


#include <stdio.h>

void send (int*);

main()
{

    int matrix[3][3]={0,1,2,3,4,5,6,7,8};

    send(matrix); // если слать так то он компилятор скажет "warning: passing arg 1 of `send' from incompatible pointer type"
        send(&matrix[0][0]); // так он ничего не скажет и всё будет ок. но это ведь одно и тоже!

    getch();

}

void send (int *matrix)
{

    printf("%i",*(matrix+3*0+0));

}



кстати на каком-то форуме читал что Шилда не рекомендуют почему-то, про Страуструпа первый раз от тебя слышу...
а что для начала не подойдёт 
Цитата

"The C programming Language Brian W. Kernighan, Dennis M. Ritchie"
 ? 
PM MAIL   Вверх
Xenon
Дата 3.5.2007, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



ressac, исходя из твой логики int*, double* - одно и тоже - это указатели "на АДРЕС и все". Но типы-то разные? И там тоже разные.


--------------------
user posted image  
PM MAIL   Вверх
Lamak
Дата 3.5.2007, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 204
Регистрация: 8.5.2005
Где: Украина,Одесса

Репутация: нет
Всего: 7



Цитата(ressac @  3.5.2007,  00:01 Найти цитируемый пост)
но это ведь одно и тоже!

ИМХО: это не одно и тоже!
Они оба указывают на одну и ту же ячейку памяти(первый элемент массива) это да ,
но типы у них разные:
  &matrix[0][0]          это указатель на int - то чего ждёт твоя функция 
  matrix                     идентификатор типа массив  - то чего  не ждёт твоя функция
Вот цитата из Страуструпа
Цитата

Если в выражении участвует идентификатор типа массив, то, исключая
случаи операнда в операциях sizeof или & и инициализатора для
ссылки ($$R.8.4.3), его тип преобразуется в указатель на первый
элемент массива
. Несмотря на это преобразование, массивы не являются
изменяемыми адресами.
 
 
--------------------
Роботы - это интересно и увлекательно! 
PM MAIL   Вверх
vinter
Дата 3.5.2007, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Lamak @  3.5.2007,  10:27 Найти цитируемый пост)
&matrix[0][0]          это указатель на int - то чего ждёт твоя функция 

поаккуратнее, а то новый холивар развяжешьsmile


--------------------
Мой блог
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0596 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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