powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Указатели
50 сообщений из 50, показаны все 2 страниц
Указатели
    #38531362
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Классический пример :
Код: plaintext
1.
2.
3.
4.
5.
6.
void swap(int &x, int &y)
{
int temp=x;
x=y;
y=temp;
}



Прокомментируйте пожалуйста, почему строчка temp=x отработает корректно, ведь x должен быть адресом, я ведь не пишу
int *temp=x;

Как я понял в x уже хранится конкретное значение. Но как я его извлёк из адреса, если операция извлечения выглядит как *x. Тогда по идее строка должна выглядеть так :
int temp=*x.

Прокомментируйте пожалуйста где я ошибаюсь, и если можно сделайте комментарий к каждой строчке функции swap. Вот например, функция принимает два дареса, или в процессе приёма данных берёт операцию адреса переменных ?Ведь вызывать я буду её как
swap(a,b) а не swap(&a,&b)

Спасибо
...
Рейтинг: 0 / 0
Указатели
    #38531579
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

ссылка -- это не указатель. Это всегда разименованный константный указатель.
При работе со ссылками у переменной сохраняется семантика самой переменной, а не указателя на переменную, но эффективно при инициализации ссылки производится как бы "передача указателя".
...
Рейтинг: 0 / 0
Указатели
    #38531600
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
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.
// Аналогичный код на указателях:

void swap(int *x, int *y)
{
int temp=*x;
*x=*y;
*y=temp;
}

// код на ссылках, с проставленными явно операциями, выполняемыми неявно компилятором. (в лишних скобках)

void swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp =  (*x);
(*x) = (*y);
(*y) = temp;
}

// код с комментариями
void swap(int &x, int &y)  // реально на физическом уровне передаются указатели на две переменные
// но в функции ты не можешь поменять эти адреса или использовать их как массивы, т.е. реализовать с ними адресную арифметику.
{
int temp=x; // эффективно выполняется код int temp = *x , т.е. в temp заносится значение, располагающееся по адресу x.
x=y; // эффективно выполняется код *x = *y , по адресу x заносится значение, лежащее по адресу y.
y=temp; // эффективно выполняется  *y = temp, по адресу y заносится значение temp.
}
...
Рейтинг: 0 / 0
Указатели
    #38532003
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, можно попробовать сделать #define swap ...
...
Рейтинг: 0 / 0
Указатели
    #38532245
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonMasterZiv, можно попробовать сделать #define swap ...
Ага, и сломать весь STL :)
...
Рейтинг: 0 / 0
Указатели
    #38532255
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вспомнился анекдот

Код: plaintext
1.
#define TRUE FALSE
...
Рейтинг: 0 / 0
Указатели
    #38532622
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv , спасибо за ответ. Вероятно я получил много ценной информации, но не всё мне понятно.

А1
"ссылка -- это не указатель. Это всегда разименованный константный указатель." Мне не очень понятно это выражение.

Как я это понимаю: согласно K&R, "Указатель - это переменная содержащая адрес другой переменной". То есть например я объявил
int *px; Так, вот элемент x-может хранить значение адреса другой переменной. Далее, адрес переменной.
int x;//объявил переменную типа int, которая имеет свой сегмент в ОП, и свой адрес в памяти, например 0x123
px=&x; //теперь в px хранится значение 0x123.

Причём тут я не провожу дифференциации на то, константный ли указатель, или нет. Константный указатель это неизменяемый адрес памяти, если я правильно понимаю.
то есть если я напишу
int *const px2;
px2=&x;//адрес x это и есть ссылка ? и это есть в данном случае разименнованный константный указатель ? а в примере выше, px ведь можно менять, и потому в том случае это не ссылка ?

А2
"При работе со ссылками у переменной сохраняется семантика самой переменной, а не указателя на переменную, но эффективно при инициализации ссылки производится как бы "передача указателя" при работе подобной этой ?
int *px=&x; //и да, я ведь не могу написать int x=&x;
Объясните пожалуйста эту фразу побробнее.

Б1
// код на ссылках, с проставленными явно операциями, выполняемыми неявно компилятором. (в лишних скобках)

void swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp = (*x);
(*x) = (*y);
(*y) = temp;
}

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

Б2
// код с комментариями
void swap(int &x, int &y) // реально на физическом уровне передаются указатели на две переменные
// но в функции ты не можешь поменять эти адреса или использовать их как массивы, т.е. реализовать с ними адресную арифметику.
{
int temp=x; // эффективно выполняется код int temp = *x , т.е. в temp заносится значение, располагающееся по адресу x.
x=y; // эффективно выполняется код *x = *y , по адресу x заносится значение, лежащее по адресу y.
y=temp; // эффективно выполняется *y = temp, по адресу y заносится значение temp.
}

Тогда зачем этот код ??Тот выше намного логичнее, что значит фраза эфективнее ? Быстрее сделать в этом примере, чем в примере выше Б1?

Прокомментируйте пожалуйста.
...
Рейтинг: 0 / 0
Указатели
    #38532623
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton, это шутка ?)

"MasterZiv, можно попробовать сделать #define swap ... "

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

define sqr(x) x*x
...
int x=5,y;
y=sqr(x+1);

Известно что препроцессор сделает.
Мне кажется, что если define где и используется, то только в тех программах которые работают со своим кодом. то есть программы который меняют свой программный код. Где то я про такое слышал.

Или это не шутка ?
Тогда define swap(x,y) а дальше как ? не {int temp; temp=x;x=y;y=temp;} ?
и то, тут вероятно ошибка
...
Рейтинг: 0 / 0
Указатели
    #38532629
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

K&R ничего не знают про int &x , потому что это С++, а они пишут про С, в котором ссылок нет вообще :)
Читайте книги по С++, если хотите разобраться.

SashaMercuryчто значит фраза эфективнее
Не "эфективнее", а "эфективно" - в данном контексте имеется в виду "в конечном итоге"

SashaMercuryvoid swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp = (*x);
(*x) = (*y);
(*y) = temp;
}

Вот!! Вот этот код мне полностью понятен, для меня он полностью логичен ! Действительно в скобках как бы неявно указатели, я это понимаю. Но эти адреса берутся в процессе вызова функции ?
Это не код, а объяснение что происходит.
Когда у вас ссылка то вы ее не разыменовываете через *. Это за вас делает компилятор С++.
...
Рейтинг: 0 / 0
Указатели
    #38532632
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyКогда у вас ссылка то вы ее не разыменовываете через *. Это за вас делает компилятор С++.
Ну и присвоение в ссылку тоже происходит без явного взятия адреса (без оператора &) - адрес присваиваемого выражения автоматически вычисляет компилятор.
...
Рейтинг: 0 / 0
Указатели
    #38532633
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, вы правы.

K&R не говорят о типе переменных как
int &x; я понял!
У нас есть , f e:
int x=100;// &x=0x123
int &rx=x;// &rx=0x123 То есть эта переменная имеет тип данных ссылка ? Это ссылочный тип данных которого нет в Си, и он появился в C++ ?
и как я понял операция взятий значения по адресу ссылки в данном случае выглядит как rx; f e: int temp=rx ??


void swap(int &x, int &y) //функция принимает именно два адреса
{
int temp=x; //в temp записывается значение по адресу x, в temp сейчас хранится конкретное целое число
x=y; //аналогично выше
y=temp; //аналогично
}

То что я написал выше корректно ?

И остался вопрос, я его практически понял подсознательно, но не конца .
используем функцию вызовом
swap(x,y)
Непонятно только это, если всё написанное выше верно
...
Рейтинг: 0 / 0
Указатели
    #38532635
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryТо что я написал выше корректно ?
да.

SashaMercuryИ остался вопрос, я его практически понял подсознательно, но не конца .
используем функцию вызовом
swap(x,y)
Непонятно только это
А вопрос-то какой? :)
...
Рейтинг: 0 / 0
Указатели
    #38532637
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
у нас есть
swap(int &a,int &b) -прототип функции

int x1=5,y=10; //&x=0x123 &y=0x127

Делаю вызов
swap(,y);

Функция принимает две переменных ссылочного типа, две ссылки, то есть в момент вызова
А- функция принимает (0x123 , 0x127 )
Б- как это происходит что берутся как бы псевдонимы этих переменных ??

ааа.стоп
я ведь пишу
int rx=&x;
И именно поэтому функция вызывается таким образом ?))

Итого:
При вызове функции (в прототипе она принимает &a,&b), в значения &a и &b записываются адреса переменных x и y !!!, и далее происходит работа с ними ?)
Я правильно понял ??

PS
"Функция принимает две переменных ссылочного типа, две ссылки, то есть в момент вызова
А- функция принимает (0x123 , 0x127 )
"
Этот мой комментарий верен, но некорректен !! Функция подставляет адреса принимаемых переменных x и у в &a и &b ! Вот это грамотный комментарий ! То есть фактически во время вызова функции происходят две операции:
int &a=x;
int &b=y;

Верно ??
...
Рейтинг: 0 / 0
Указатели
    #38532638
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даже не подставляет, а делает так что параметры a и b берут значение из той же области памяти что и x с y
...
Рейтинг: 0 / 0
Указатели
    #38532640
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЭтот мой комментарий верен, но некорректен !!
Это шедевр :)


SashaMercuryФункция подставляет адреса принимаемых переменных x и у в &a и &b ! Вот это грамотный комментарий
Ну что вы себя путаете этими &. Нет там никаких &a. & относится к типу а не к переменной.

Если кратко то при вызове функции с параметром ссылкой происходит следущее:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
void swap(int &x, int &y)
{
    int temp=x;
    x=y;
    y=temp;
}
...

int x=5,y=10;

// при вызове
swap(x, y);
// генерится следущий код
// int& tmp1 = x;
// int& tmp2 = y;
// swap(tmp1, tmp2);
...
Рейтинг: 0 / 0
Указатели
    #38532641
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

// при вызове
swap(x, y);
// генерится следущий код
// int& tmp1 = x;
// int& tmp2 = y;
// swap(tmp1, tmp2);

Я понял !))) Спасибо!

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

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

м. А указатель это переменная хранящая адрес другой переменной. Интересные комбинации могут получить из указателей и адресов.


Anatoly Moskovsky и MasterZiv, Спасибо за все объяснения! Я понял !
...
Рейтинг: 0 / 0
Указатели
    #38532642
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, объявления вида:
Код: plaintext
1.
2.
int& rx;
int ℞



Как я понял аналогичны, но ведь очевидно что первое int& rx; будет более грамотным, разве нет ? Или тут такая-же ситуация как с обратным чтением
const int*- указатель типа int на константу
int *const -константный указатель на целое число

да нет, всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
...
Рейтинг: 0 / 0
Указатели
    #38532644
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryКстати, объявления вида:
Код: plaintext
1.
2.
int& rx;
int ℞



Как я понял аналогичны, но ведь очевидно что первое int& rx; будет более грамотным, разве нет ? Или тут такая-же ситуация как с обратным чтением
const int*- указатель типа int на константу
int *const -константный указатель на целое число

да нет, всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
Это исключительно вопрос стиля, к чему примыкает &. Есть фанаты и того и того, и ругаются в инете они так же яростно как и фанаты отступов пробелами и табами :)

ЗЫ. Применяйте тег SRC чтобы те было такого: ℞
...
Рейтинг: 0 / 0
Указатели
    #38532646
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например,

Фанат1всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
Фанат2зато int& x, y; выглядит как будто у обех переменных тип int&, а на самом деле - только у первой
Фанат1так нефиг в одной строке объявлять несколько переменных
ну и так далее ... :)
...
Рейтинг: 0 / 0
Указатели
    #38532653
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
про SRC понял, окей.

"так нефиг в одной строке объявлять несколько переменных "
...
Рейтинг: 0 / 0
Указатели
    #38532779
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСейчас мне стало казаться что ссылочный тип данных это мощно, то есть я могу именовать одну и ту же часть памяти через различные переменные, и менять значения этой части памяти через различные переменные. Хотя наверное есть и недостатки,
!

можно случайно забыть о связи нескольких переменных, изменить значение одной, и поменяют значения все другие, указывающие изменённый участок памяти.
![/quot]

А ещё можно забыть, как дышать, и случайно задохнуться....

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

SashaMercuryА есть ли какое-либо ограничение на максимальное количество переменных указывающих на именованный участок памяти ?


Нет, ограничений нет.
...
Рейтинг: 0 / 0
Указатели
    #38533015
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryДаже придумал у себя в голове ещё один пример, с помощью этих ссылочных переменных мы открываем доступ к значению переменных через другой "порт".


ссылка это другое имя переменной, его алиас (псевдоним) и т.п. поэтому не инициализированных ссылок не бывает в природе. это всегда отсылка на уже существующий объект.
...
Рейтинг: 0 / 0
Указатели
    #38533893
z
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
z
Гость
Anatoly MoskovskySashaMercury,

K&R ничего не знают про int &x , потому что это С++, а они пишут про С, в котором ссылок нет вообще :)
Читайте книги по С++, если хотите разобраться.



Читаем:
5.1. Указатели и адреса
http://lib.ru/CTOTOR/kernigan.txt

Кстати, пример со SWAP
именно оттуда...

SWAP(A, B);

определив функцию SWAP при этом следующим образом:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 SWAP(X, Y)      /* WRONG */
 INT X, Y;
 {
    INT TEMP;

    TEMP = X;
    X = Y;
    Y = TEMP;
 }


Модератор: Отредактировано
...
Рейтинг: 0 / 0
Указатели
    #38533954
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
z,

вопрос изначально был про ссылки, а не про указатели. ссылок в С нет.
...
Рейтинг: 0 / 0
Указатели
    #38534910
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Огромная просьба ко всем: не кормите троллей.
Флуд удаляется...
...
Рейтинг: 0 / 0
Указатели
    #38537042
z
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
z
Гость
MasterZivz,

вопрос изначально был про ссылки, а не про указатели. ссылок в С нет.
Название ссылка в C++ может приводить к путанице, так как в информатике, и в С в частности, под ссылкой понимается обобщенный концептуальный тип, а указатели и С++ ссылки являются специфическими реализациями ссылочного типа.
...
Рейтинг: 0 / 0
Указатели
    #38537300
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Код: plaintext
1.
#define sqr(x) (x)*(x)
...
Рейтинг: 0 / 0
Указатели
    #38537313
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include<stdio.h>

#define SWAP(x,y) \
int temp ## __LINE__ = x; x = y; y = temp ## __LINE__;\

int main(int argc,char **argv){

	int x=2;
	int y=3;

	SWAP(x,y);
	
	printf("x= %i, y = %i\n",x,y);


}



Хе-хе!
...
Рейтинг: 0 / 0
Указатели
    #38537334
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Код: plaintext
1.
2.
#define SWAP(x,y) \
int temp ## __LINE__ = x; x = y; y = temp ## __LINE__;\



Если речь все-таки про С, то должно быть так:
Код: plaintext
1.
2.
#define SWAP(x,y) \
do { int temp ## __LINE__ = x; x = y; y = temp ## __LINE__; } while (0)


потому что С не позволяет объявлять переменные вперемешку с кодом.

А если про С++, то std::swap
...
Рейтинг: 0 / 0
Указатели
    #38537338
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, хех... добавлю в новых одинацдатых сях вон оно как определено:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
template <class T> void swap (T& a, T& b)
{
  T c(std::move(a)); a=std::move(b); b=std::move(c);
}
template <class T, size_t N> void swap (T &a[N], T &b[N])
{
  for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}


А второй шаблон насколько я понял определяет свап для двух векторов
...
Рейтинг: 0 / 0
Указатели
    #38537355
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskymayton
Код: plaintext
1.
2.
#define SWAP(x,y) \
int temp ## __LINE__ = x; x = y; y = temp ## __LINE__;\



Если речь все-таки про С, то должно быть так:
Код: plaintext
1.
2.
#define SWAP(x,y) \
do { int temp ## __LINE__ = x; x = y; y = temp ## __LINE__; } while (0)


потому что С не позволяет объявлять переменные вперемешку с кодом.

А если про С++, то std::swap Во первых, современный C - позволяет. Сейчас чтобы компилятор начал ругаться на объявление переменных не в начале блока надо специально включать режим совместимости со старыми стандартами.
Во вторых, do while не обязателен даже в старых стандартах. Достаточно фигурных скобок. Главное чтобы блок был объявлен.
...
Рейтинг: 0 / 0
Указатели
    #38537544
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlВо первых, современный C - позволяет. Сейчас чтобы компилятор начал ругаться на объявление переменных не в начале блока надо специально включать режим
Во вторых, do while не обязателен даже в старых стандартах. Достаточно фигурных скобок. Главное чтобы блок был объявлен.
do while нужно чтобы макрос можно было применять везде где допустим вызов функции.
А просто скобки не везде допустимы.
Например это не будет работать
Код: plaintext
1.
2.
3.
4.
if (a)
   swap(x, y);
else
   other();


gcc умеет еще ({}) для тех же целей, но многие другие компиляторы не умеют.

Ну а насчет "надо специально включать режим" ругани компилятора, это не совсем соответствует действительности. Например при сборке ядра и модулей линукса по умолчанию выдаются предупреждения на смешанный код. Так что обобщать тоже не надо.

Поэтому если есть возможность без каких либо усилий сделать универсальный макрос для всех компиляторов С, не вижу причин делать макрос который будет работать только с некоторыми компиляторами / опциями, просто потому что это возможно. Главное достоинство С - это кроссплатформенность. Не стоит лишать его этого без веских причин.
...
Рейтинг: 0 / 0
Указатели
    #38537547
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА просто скобки не везде допустимы.
Например это не будет работать
Код: plaintext
1.
2.
3.
4.
if (a)
   swap(x, y);
else
   other();

Почему не будет??? У меня работает. Если макрос окружен просто скобками, то получится просто командный блок у if, а если с do{}while(0) то получится разовый цикл у if, который имеет в себе блок. В чем разница то?

Anatoly Moskovskygcc умеет еще ({}) для тех же целей, но многие другие компиляторы не умеют.А кто-то пользуется чем-то другим? Какие странные люди.

Anatoly MoskovskyНу а насчет "надо специально включать режим" ругани компилятора, это не совсем соответствует действительности. Например при сборке ядра и модулей линукса по умолчанию выдаются предупреждения на смешанный код. Так что обобщать тоже не надо.Ну так там этот режим включен.
Для gcc это комбинация ключиков -std=c89 -pedantic.
Для всех компиляторов у которых по умолчанию включен более поздний стандарт (а это все современные насколько я знаю) объявление переменной может быть где угодно, главное чтобы перед ее первым использованием...

Anatoly MoskovskyПоэтому если есть возможность без каких либо усилий сделать универсальный макрос для всех компиляторов С, не вижу причин делать макрос который будет работать только с некоторыми компиляторами / опциями, просто потому что это возможно. Главное достоинство С - это кроссплатформенность. Не стоит лишать его этого без веских причин.В общем-то да. С этим утверждением спорить нельзя.
...
Рейтинг: 0 / 0
Указатели
    #38537549
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlПочему не будет??? У меня работает. Если макрос окружен просто скобками, то получится просто командный блок у if, а если с do{}while(0) то получится разовый цикл у if, который имеет в себе блок. В чем разница то?
Если просто скобки, то макрос развернется в такой код
Код: plaintext
1.
2.
3.
4.
if (a)
   {...};
else
   other();


И я очень сомневаюсь, что он у вас "работает"
...
Рейтинг: 0 / 0
Указатели
    #38537556
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

ну уел... :-)
...
Рейтинг: 0 / 0
Указатели
    #38538563
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton

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

Код: plaintext
1.
2.
3.
4.
define sqr(x) x*x
...
int x=5,y;
y=sqr(x+1); "



Понятно что будет правильно так как вы написали :
Код: plaintext
1.
#define sqr(x) (x)*(x)



Я примёл тот комментарий так как хотел прокомментировать, что использование директив препроцессора по типу #define чаще всего нежелательно.

И вот кстати, такой общий вопрос. В теории языков программирования есть понятия аналогичное полноте пространства в математике, так вот интересно, можно ли сейчас обойтись вообще без таких замен кода подобных
Код: plaintext
1.
#define sqr(x) (x)*(x)

. То есть, можно ли написать программный код на языках C or С++ для любого алгоритма без использования данной директивы. И кстати, как я понимаю, без директив #include тоже можно обойтись, если вставлять код из библиотек вручную, но это гемор и бред конечно, наверное. Да и исчезнет функция предварительно откомпилированных заголовков, а это замедлит компиляцию/трансляцию программ. Мой вопрос касается только директивы #define.


Anatoly Moskovsky
Ваш спор, с коллегами mayton и White Owl , очень интересен, я уверен что из него можно извлечь много информации, сейчас буду изучать, ибо пока вопросов слишком много
...
Рейтинг: 0 / 0
Указатели
    #38538565
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
//надо всё-таки использовать предварительный просмотр
"Я примёл тот комментарий так как хотел прокомментировать, что использование директив препроцессора по типу #define чаще всего нежелательно."
так как может привести к трудновыявивым ошибкам.
...
Рейтинг: 0 / 0
Указатели
    #38538715
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИ кстати, как я понимаю, без директив #include тоже можно обойтись, если вставлять код из библиотек вручную, но это гемор и бред конечно, наверное.
Это скорее всего бред
...
Рейтинг: 0 / 0
Указатели
    #38538906
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonSashaMercuryИ кстати, как я понимаю, без директив #include тоже можно обойтись, если вставлять код из библиотек вручную, но это гемор и бред конечно, наверное.
Это скорее всего бред
Ну почти бред :)
Сейчас ведется развитие С++ в сторону директивы import которая должна заменить #include в том же смысле как инлайн функции заменили макросы. То есть это будет не препроцессинг, а полноценная фича языка.
Первыми идет в этом направлении Clang.
Посмотрим что получится.
Как минимум скорость компиляции должна будет улучшиться.
...
Рейтинг: 0 / 0
Указатели
    #38539392
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А ведь большие голубые пилили такую фишку в Visual Age C++ ...
Но, линейка сдохла и фишки нет.
...
Рейтинг: 0 / 0
Указатели
    #38539509
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, C++ и так сложен макропроцессингом и шаблонами. А добавление
к нему еще и директив статического импорта сделает бинарь непрогнозируемо
большим и запутанным. Я-бы лучше двигался в сторону создания С++ runtime.
...
Рейтинг: 0 / 0
Указатели
    #38539551
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Импорт как раз упростит все.
Да и рантайм и так уже есть: libc + libstdc++ :)

А кому страшно, пусть сидит в своей джаве
...
Рейтинг: 0 / 0
Указатели
    #38539557
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Толик. Кольцо власти жжёт мне руку...
...
Рейтинг: 0 / 0
Указатели
    #38539891
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИ кстати, как я понимаю, без директив #include тоже можно обойтись, если вставлять код из библиотек вручную, но это гемор и бред конечно, наверное.

maytonЭто скорее всего бред

Anatoly Moskovsky Ну почти бред :)

Согласен. а в целом, я был прав ? Такие вставки в код программы теоретически возможны ?

maytonAnatoly Moskovsky, C++ и так сложен макропроцессингом и шаблонами


не так много работал с шаблонами.Но всё же.
В С тип данных каждой переменной устанавливаются во время компиляции, используется статическая типизация. И это с одной стороны здорово, уменьшаем количество возможных ошибок, увеличиваем скорость работы программы, во время выполнения программы не происходят проверки типов. Это в сравнении с динамической типизацией. Есть и минусы, например нам необходимо отсортировать массив чисел, и было бы здорово если бы могли написать void sorting(any_type arr[]), вот в этом случае шаблоны (или ,как я понимаю, обобщённое программирование) будут очень удобны. Значит он не сложен шаблонами, а наоборот, хорошо что в нём есть шаблоны. Что я упускаю ? Почему он сложен ими ?

Basil A. Sidorov большие голубые

Кто такие большие голубые ?
...
Рейтинг: 0 / 0
Указатели
    #38539893
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно ли задать переменной адрес где она будет находиться ?
f e:
int a;
&a=0x123;
Наверное нет ? Почему ? А если да, то подскажите пожалуйста как
...
Рейтинг: 0 / 0
Указатели
    #38539937
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСогласен. а в целом, я был прав ? Такие вставки в код программы теоретически возможны ?Возможны.

SashaMercuryне так много работал с шаблонами.Но всё же.
В С тип данных каждой переменной устанавливаются во время компиляции, используется статическая типизация. И это с одной стороны здорово, уменьшаем количество возможных ошибок, увеличиваем скорость работы программы, во время выполнения программы не происходят проверки типов. Это в сравнении с динамической типизацией. Есть и минусы, например нам необходимо отсортировать массив чисел, и было бы здорово если бы могли написать void sorting(any_type arr[]), вот в этом случае шаблоны (или ,как я понимаю, обобщённое программирование) будут очень удобны. Значит он не сложен шаблонами, а наоборот, хорошо что в нём есть шаблоны. Что я упускаю ? Почему он сложен ими ?Потому что есть очень мало задач в которых подобный "any_type" имеет смысл. Но любители шаблонов умудряются писать их для каждого чиха.


SashaMercuryКто такие большие голубые ?IBM

SashaMercuryМожно ли задать переменной адрес где она будет находиться ?
f e:
int a;
&a=0x123;
Наверное нет ? Почему ? А если да, то подскажите пожалуйста как Потому что нет никакой разницы на каком адресе находится переменная.
Код: plaintext
1.
2.
int *a  = 0x123;
#define varA (*a)
...
Рейтинг: 0 / 0
Указатели
    #38539997
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl Потому что нет никакой разницы на каком адресе находится переменная.

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int a;
	int* pa;
	a = 5;
	pa = &a;
	std::cout << a << " " << &a << " " << pa<<std::endl<<"Array"<<std::endl;
	for (int i = 0; i <= 1000; ++i)
	{
		std::cout << i << " " << (pa + i) << " " << *(pa + i) << std::endl;
	}
	return 0;



Иногда вылетает на 100 шаге, а иногда на 500. С чем это связано ? С тем размером памяти что выделен в данный момент потоку программы в ОП ?
...
Рейтинг: 0 / 0
Указатели
    #38540014
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryWhite Owl Потому что нет никакой разницы на каком адресе находится переменная.

Я не могу спорить по этому поводу. Но не убедился что это действительно так. А если это так, то тогда объясните почему программе совершенно безразлично где хранятся данные, и почему это нигде не может понадобиться ?
Потому что ОС решает где выделить место и дает программе адрес этого места. За пределы этого места лезть не стоит, т.к. оно выделено для других переменных.
Есть хорошая книжка где это расписано подробно: Джеффри Рихтер "Windows для профессионалов".
ЧАСТЬ III УПРАВЛЕНИЕ ПАМЯТЬЮ (по ссылке скан позорненький, поищи с лучшим качеством или бумажную купи)
Книга хорошая, расписаны все внутренние особенности виндовса. Я по ней изучал когда-то.
SashaMercuryИногда вылетает на 100 шаге, а иногда на 500. С чем это связано ? С тем размером памяти что выделен в данный момент потоку программы в ОП ?
Если кратко: память выделяется страницами (по 4Кб если не ошибаюсь), пока ты читаешь выделенную память - работает, как только натыкаешься на адрес под который не выделена реальная память - вылетает.
...
Рейтинг: 0 / 0
Указатели
    #38540101
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ребята, о чем топик? просто поговорить?

есть какие-то новые вопросы -- делайте новые топики.
...
Рейтинг: 0 / 0
Указатели
    #38541417
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_T,
окей,я записал ) Спасибо :-)
...
Рейтинг: 0 / 0
50 сообщений из 50, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Указатели
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]