Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.70/88: Рейтинг темы: голосов - 88, средняя оценка - 4.70
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11

Ссылки и указатели

01.03.2011, 12:10. Показов 18570. Ответов 54
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.
Возможно было. В чем существенная разница между передачей данных в функцию по ссылке или указателю. В каких случаях вы бы что рекоммендовали. Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.03.2011, 12:10
Ответы с готовыми решениями:

Указатели и Ссылки
извеняюсь,но никак не могу понять. int sum(int* inLeft, int* inRight) { if(inLeft == inRight) return *inLeft; ...

Ссылки и указатели
#include <iostream> using namespace std; int main() { int *n=new int{1,2}; cout<<&n<<' '<<&n<<' '<<&n<<endl; return...

Ссылки и указатели
Всем привет. Совсем запутался с ссылками и указателями. Помогите решать задачку: Функция принимает два аргумента, число с плавающей...

54
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:21
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от kravam Посмотреть сообщение
компилится, шеф
Не должно! Какой компилятор? Выкиньте его на свалку, он нарушает стандарт.
С преобразованием типа - будет компилиться, без преобразования - не должно.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
15.07.2011, 18:36
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Не должно! Какой компилятор? Выкиньте его на свалку, он нарушает стандарт
gcc в режиме Си вроде бы как сожрёт это дело
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:41
Насколько помню, в Си не было ссылок...
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 18:44
ДРузья, я был неправ. Но это бросает тень на меня и только.

Итак, мне нравится когда всё о чём я говорил компилится с преобразованием типов
C++
1
        p=(void(*)())&f;
Это плохо.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
15.07.2011, 18:46
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Насколько помню, в Си не было ссылок...
А при чём тут ссылки? Речь идёт о преобразовании типа над указателями на функцию (первый пример из поста #22). Далее в посте #38 я нарисовал пример, отрезавшись от Си++ (чтобы его можно было компилять и на Си, и на Си++). В режиме Си на, к примеру, борландовском компиляторе он не пройдёт компиляцию, а на gcc - пройдёт. Ибо gcc по умолчанию работает в некотором своём расширении, который допускает больше безобразия, нежели стандартный Си
1
15.07.2011, 18:47

Не по теме:

— Доктор, когда я делаю вот так, мне больно!
— А вы не делайте "вот так"!

2
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:48
Цитата Сообщение от kravam Посмотреть сообщение
ДРузья, я был неправ. Но это бросает тень на меня и только.

Итак, мне нравится когда всё о чём я говорил компилится с преобразованием типов
C++
1
        p=(void(*)())&f;
Это плохо.
Не... Просто аккуратно надо.
Я когда-то исследовал функции с переменным числом параметров и тоже вовсю использовал преобразование указателей. Было интересно передать в функцию с переменным числом параметров указатели на функции с разным числом параметров и там все их вызвать...
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
15.07.2011, 19:14
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Я когда-то исследовал функции с переменным числом параметров и тоже вовсю использовал преобразование указателей. Было интересно передать в функцию с переменным числом параметров указатели на функции с разным числом параметров и там все их вызвать...
С точки зрения языка сие допустимо, но по сути дела это UB, потому как в точке вызова и в точке самой функции должны быть одинаковые прототипы. Возьмём пример из двух файлов:

C
1
2
3
4
5
6
7
8
extern void func (float f1, float f2);
 
int
main (void)
{
  func (1.25, 2.75);
  return 0;
}
C
1
2
3
4
5
6
7
#include <stdio.h>
 
void
func (int f1, int f2)
{
  printf ("f1=%x, f2=%x\n", f1, f2);
}
Мы видим, что в точке вызова прототип описан как с двумя float'ами, а в точке реализации - с двумя int'ами. Два файла компилируются раздельно, а потому для компилятора они оба корректные. Линкер работает только с именами: он видит, что в одном модуле есть определение символа "func", а в другом - использование символа с таким же именем, а потому он свяжет эти две точки и всё. Такой код будет работать. При исполнении он выдаст:

Code
1
f1=3fa00000, f2=40300000
В точке вызова компилятор передаст параметры, которые есть наборы битов для представления констант 1.25 и 2.75 как float. А а в самой функции из этого же места прочтутся эти же самые наборы битов, но будут трактоваться как int'ы (от чего и напечатаны такие значения). Казалось бы, что поведение программы всё равно оказывается детерминированным. А на самом деле это не так. В случае i386 при передаче целых и плавающих значений используются одни и те же программные соглашения. В нашем случае размер int'а совпадает с размером float'а, а потому место, через которое передаются параметры (видимо это стек) совпадёт с местом, откуда они читаются. На архитектуре sparc v9 программные соглашения устроены таким образом, что для целых и плавающих значений используются разные правила передачи параметров. В этом случае параметры типа float передадутся на плавающих регистрах, а параметры типа int будут прочитаны с целочисленных регистров (и окажутся неинициализированными).

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

Ну и такие же риски имеются, если с var_arg'ами работать так, как в начальных примерах твоей статьи - непосредственно через указатели

Добавлено через 1 минуту
Да, забыл сказать. Это пример работает только в Си, потому как с точки зрения Си++ функции с одним именем, но разными типами параметров - это разные функции
8
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 23:13
такс всеравно не до конца пока улавливаю суть.
с указателем то ещё ладно, но для статической переменной откуда память то берется?
Закинул все это дело в вечный цикл, подождал минут в 20 в надежде что оно вылетит, но нет..
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
 
class B
{
public:
    int* a;
    int b;
    void func2()
    {
        a=new int;
        *a=10;
        b=250;
        cout<<*a<<" "<<b<<endl;
    }
};
 
int main ()
{
    while(1)
    {
        B *p;
        p->func2();
        *p->a=2222;
        p->b=20;
        cout<<*p->a<<" "<<p->b<<endl;
    }
    return 0;
}
0
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
15.07.2011, 23:37
Цитата Сообщение от silentnuke Посмотреть сообщение
B *p; p->func2(); *p->a=2222;
так ваще делать нельзя.

по идее должно вылететь.

побольше выделять попробуй:
C++
1
2
3
4
5
    int counter=0;
    while (1) {
        int* p = new int[40000];
        std::cout << "ok: " << ++counter << '\n';
    }
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 23:40
Цитата Сообщение от silentnuke Посмотреть сообщение
такс всеравно не до конца пока улавливаю суть.
с указателем то ещё ладно, но для статической переменной откуда память то берется?
Закинул все это дело в вечный цикл, подождал минут в 20 в надежде что оно вылетит, но нет..
Все переменные С++ распределяются на три вида по виду памяти:
static storage (глобальные и статические переменные), automatic storage (локальные перменные) и dynamic storage (динамические переменные). Для статических-глобальных объектов память рампределяет компилятор при трансляции. Они "живут" все время, пока работает программа. Локальные объекты "рождаются" в стеке, там же и "помирают" во время работы программы. А динамические объекты создаются явно во время работы программы в куче. И их надо явно "убивать".
Поскольку куча - 2 гига (виртуальная память), то выделяя по одному int, вы нескоро ее исчерпаете.
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 23:54
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Все переменные С++ распределяются на три вида по виду памяти:
static storage (глобальные и статические переменные), automatic storage (локальные перменные) и dynamic storage (динамические переменные). Для статических-глобальных объектов память рампределяет компилятор при трансляции. Они "живут" все время, пока работает программа. Локальные объекты "рождаются" в стеке, там же и "помирают" во время работы программы. А динамические объекты создаются явно во время работы программы в куче. И их надо явно "убивать".
Поскольку куча - 2 гига (виртуальная память), то выделяя по одному int, вы нескоро ее исчерпаете.
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
16.07.2011, 00:01
Цитата Сообщение от silentnuke Посмотреть сообщение
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
VS 2008 в отладочном режиме тут же выдала
Run-Time Check Failure #3 - The variable 'p' is being used without being initialized.
То есть, у тебя указатель не инициализирован, а ты пытаешься вызвать метод через него.
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
16.07.2011, 00:02
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
динамические объекты создаются явно во время работы программы в куче
Если имеются ввиду операторы new/delete, то у Herb Sutter применяется термин "Free Store", а не "Heap".

Exceptional C++ - Memory Management - Part I
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.07.2011, 00:08
Цитата Сообщение от silentnuke Посмотреть сообщение
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
Указатель p не инициализировался, а потому там мусорное значение. Звёзды встали так, что этот мусор оказался валидным адресом. И по этому адресу обращение не сломалось, при этом ты записывал в поле a, а потому просто гадил в чью-то память. Опять-таки звёзды встали так, что это оказалось нефатальным.

То, что у тебя цикл бесконечный - по сути ничего не означает. Каждый раз переменная p у тебя лежала в одном и том же месте стека, а потому каждый раз в ней был записан один и тот же мусор. А следовательно ты каждый раз гадил в одну и ту же память. Т.е. что цикл из одной итерации, что из бесконечного количества - в данном случае роли не играет

Добавлено через 2 минуты
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
То есть, у тебя указатель не инициализирован, а ты пытаешься вызвать метод через него
Конкретное значение указателя роли не играет, ибо на вызове метода это никак не отражается (см. по ссылкам из поста #24). Реальная засада могла быть только при записи в поля a и b. Но, как уже писал выше, звёзды встали так, что мусорное значение оказалось валидным адресом, нагадив по которому ничего страшного не произошло
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.07.2011, 00:08

Указатели и ссылки?
Ниже приведёна программы которая вызывает функцию. В функции происходит следующее создаются 2 массива в которые записыватся чётные и...

Ссылки, указатели
Доброго времени. Как, используя ссылки, указатели и, возможно, другие приемы сделать что-то вроде этого?: int a = 1; int b = 2; ...

Указатели и ссылки
а если написать return this тогда что вернется? и как определить? П.5.18.Правил Запрещено размещать задания и решения в виде картинок...

Ссылки и указатели
Добрый день, не могу понять чем помогают при использовании указатели и ссылки? Есть код на c++ #progma once class well { ...

Указатели и ссылки
Собственно, не могу до конца осознать как это работает, вот пример из вики(комменты входят в пример) int n = 6; // Объявление...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
Новые блоги и статьи
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
Текстовый слайдер с нумерацией страниц и кроссбраузерность.
russiannick 18.07.2026
Один мой друг написал текстовый слайдер с нумерацией страниц. Сегодня я расскажу как он умудрился подружить его с кроссбраузерностью. Очевидно сложно угодить с шириной каждому браузеру. Один крадет. . .
Грибы - это мемы, дерево - это человек. Применение микоризной модели к теории меметики Докинза.
anaschu 18.07.2026
Меметический изоморфизм теории «всего»: Грибная сукцессия как модель эволюции идей Докинза Базовый код системы ОДУ микоризной сукцессии описывает не просто биологию, а универсальную. . .
Грибы - это корпорации, деревья - это государства. Механизм массонского захвата власти
anaschu 18.07.2026
Макроэкономический изоморфизм теории «всего»: Грибная сукцессия как модель транснационального капитализма Базовый код системы ОДУ микоризной сукцессии описывает не просто биологию, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru