Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

sizeof()

11K
15 августа 2005 года
sergmagic
10 / / 15.07.2005
Почему, передавая массив в функцию-член, sizeof(этот массив) возвращает неверное значение?(C++)
299
15 августа 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by sergmagic
Почему, передавая массив в функцию-член, sizeof(этот массив) возвращает неверное значение?(C++)


Пример бы кода привел....

3
15 августа 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by sergmagic
Почему, передавая массив в функцию-член, sizeof(этот массив) возвращает неверное значение?(C++)



Массив передаешь по указателю на элемент или по указателю/ссылке на весь массив?

11K
19 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by 3D Bob
Пример бы кода привел....



X::X(int a,int b,double c[])
{
if((a*b)!=sizeof(c)) error("Fuck");
...
}
Все время выдает ошибку(Fuck), хотя a=4 b=4 c[16]={1,2,..,16} к примеру.

299
20 августа 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by sergmagic
X::X(int a,int b,double c[])
{
if((a*b)!=sizeof(c)) error("Fuck");
...
}
Все время выдает ошибку(Fuck), хотя a=4 b=4 c[16]={1,2,..,16} к примеру.



Все правильно. Размер double c[16] = 128
Так как размер double 8 байт. (8*16=128)
Это размер char 1 байт.
sizeof возвращает не размер масива. А размер занимаемой памяти.

11K
21 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by 3D Bob
Все правильно. Размер double c[16] = 128
Так как размер double 8 байт. (8*16=128)
Это размер char 1 байт.
sizeof возвращает не размер масива. А размер занимаемой памяти.



Все равно выдает error, почемуто sizeof(c) возвращает 4. :???:

247
21 августа 2005 года
wanja
1.2K / / 03.02.2003
Цитата:
Originally posted by sergmagic
Все равно выдает error, почемуто sizeof(c) возвращает 4. :???:


Наверное, размер указателя.

3
21 августа 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by sergmagic
X::X(int a,int b,double c[])
{
if((a*b)!=sizeof(c)) error("Fuck");
...
}
Все время выдает ошибку(Fuck), хотя a=4 b=4 c[16]={1,2,..,16} к примеру.



Такая запись в С++ равнозначна передаче по указателю, т.о. sizeof тебе возвращает размер указателя (4).
Для получения размера надо передавать массив по ссылке:

 
Код:
template<typename T>
X::X(int a, int b, T& c)
{
if((a*b)!=sizeof(c)) error("Not equal");
...
}


P.S. Не пишите в коде ругательства и прочие неосмысленные фразы, даже если этот код тестовый.
11K
23 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by Green
Такая запись в С++ равнозначна передаче по указателю, т.о. sizeof тебе возвращает размер указателя (4).
Для получения размера надо передавать массив по ссылке:
 
Код:
template<typename T>
X::X(int a, int b, T& c)
{
if((a*b)!=sizeof(c)) error("Not equal");
...
}


P.S. Не пишите в коде ругательства и прочие неосмысленные фразы, даже если этот код тестовый.



Ругаться больше не буду ;) .Все равно у меня не выходит, теперь возвращается sizeof(c) равное 8, т.е одного элемента double, а не массива. :o

3
23 августа 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by sergmagic
Ругаться больше не буду ;) .Все равно у меня не выходит, теперь возвращается sizeof(c) равное 8, т.е одного элемента double, а не массива. :o



Ну ка покажи, как ты мой пример перекроил?

11K
25 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by Green
Ну ка покажи, как ты мой пример перекроил?



class X
{
public:
X(int a,int b,double& c);
~X();
};
X::X (int a,int b,double& c)
{
if((a*b*8)!=sizeof(c)) {printf("No");getch();}
else {printf("Ok");getch();}
return;
}
X::~X()
{
return;
}
main()
{
double c[16] ={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.};
X exemple(4,4,*c);
}
........screen: No

12K
25 августа 2005 года
dolpin_spb
9 / / 18.08.2005
Цитата:
Originally posted by sergmagic
Почему, передавая массив в функцию-член, sizeof(этот массив) возвращает неверное значение?(C++)


Если мне память не изменяет - данный оператор сообщает длину переменной в байтах.

Точно отвечу, что применяется к потокам: TStream, TMemoryStream, TFileStream и т.д. Можно также юзать при работе с вариантами (Variants).

Вопрос: что ты хочешь получить, используя свою функцию???

299
25 августа 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by sergmagic
class X
{
public:
X(int a,int b,double& c);
~X();
};
X::X (int a,int b,double& c)
{
if((a*b*8)!=sizeof(c)) {printf("No");getch();}
else {printf("Ok");getch();}
return;
}
X::~X()
{
return;
}
main()
{
double c[16] ={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.};
X exemple(4,4,*c);
}
........screen: No



Итак говорю твою глобальную ошибку.
в твоем случае с это указатель.
И объясняю основы Си++

твой с, это указатель.
с по умолчанию равено &с[0]

В твоем случае
X exemple(4,4,*c);
Ты разыменовываешь только первый член, слабо в функции обратится и посмотреть какой член ты передаешь? Ты передаешь только лишь первый символ так как. *с = с[0];
(сам еще раз сейчас проверил)
Далее для передачи мсива в функцию обычно создают такую функцию.

X(int a,int b,double c[]);

Далее выдержка из справочника

Цитата:

Если массив является параметром функции, то компилятор игнорирует указанный размер а настоящим типом параметра бдет тип-указатель.
(с) Рэй Лишнер.

11K
25 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by 3D Bob
Итак говорю твою глобальную ошибку.
в твоем случае с это указатель.
И объясняю основы Си++

твой с, это указатель.
с по умолчанию равено &с[0]

В твоем случае
X exemple(4,4,*c);
Ты разыменовываешь только первый член, слабо в функции обратится и посмотреть какой член ты передаешь? Ты передаешь только лишь первый символ так как. *с = с[0];
(сам еще раз сейчас проверил)
Далее для передачи мсива в функцию обычно создают такую функцию.

X(int a,int b,double c[]);

Далее выдержка из справочника



Спасибо за объяснения, до этогот я и сам уже допер, но все-таки, как определить размер массива, передаваемого в функцию, к примеру так:X(int a,int b,double c[]);

3
25 августа 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by sergmagic

class X
{
public:
X(int a,int b,double& c);
~X();
};


М-да... Сути ты не понял. Придется разжевывать.
В данном случае третий аргумент - ссылка на double, а не на массив.

Минус языка С++, в том, что (видимо, в силу обратной совместимости с С) не предоставляется возможным определить массив в определении функции. Все попытки типа:
X(int a,int b,double c[]);
X(int a,int b,double c[10]);
приводят к тому, что параметр с определяется, как указатель на double. Естественно информация о размерности теряется.

В С++ есть такая классная вещь, как ссылка. Она позволяет не копировать объекты, а ссылаться на них. Это не аналог указателя, как обычно ошибаются новички. Ссылка содержит информацию о ссылаемом типе, а именно размер. Т.е. sizeof от ссылки равен sizeof от самого типа.
Это можно использовать. Но синтаксис языка С++ не дает возможность определить ссылку на массив напрямую. Ну а действительно, как?
double& c[10]; - это получается массив ссылок
double[10]& c; - это вообще ахинея, после типа должно идти имя, а не размерность.

Но это можно сделать через typedef:

 
Код:
typedef double DoubleArray[10]; // определили новый тип - массив

DoubleArray c; // определили переменную типа массив

// теперь можно и в методах принимать
X::X (int a, int b, DoubleArray& c);

Но такой способ не очень удобный, т.к. предполагает определение используемых типов с соотв. именами.
И к нам на помошь приходит ещё один плюс С++, - это шаблоны, которые ты так бесцеремонно вырезал из моего примера.
 
Код:
template<typename T>
X::X(int a, int b, T& c); // здесь тип не указан явно, он определится при инстанциировании шаблона

// инстанциируем шаблон типом double[16]
double c[16] ={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.};
X exemple(4,4,c);


Цитата:
Originally posted by 3D Bob

твой с, это указатель.
с по умолчанию равено &с[0]


Это неверно!
Это не указатель, а массив. Просто в большинстве случаев массив неявно приводится к указателю на первый элемент.

11K
26 августа 2005 года
sergmagic
10 / / 15.07.2005
Цитата:
Originally posted by Green
М-да... Сути ты не понял. Придется разжевывать.



Спасибо большое. Теперь всё понятно. Учиться, учиться, учиться :)

11K
28 августа 2005 года
dosER
17 / / 04.07.2005
почему бы не передавать в функцию размер массива, а не сам массив или указатель на него.:)
299
28 августа 2005 года
3D Bob
885 / / 18.04.2005
Я думаю у человека скорее чисто позновательный вопрос, а не практический.
11K
28 августа 2005 года
dosER
17 / / 04.07.2005
Цитата:
Originally posted by Green

...
double& c[10]; - это получается массив ссылок
double[10]& c; - это вообще ахинея, после типа должно идти имя, а не размерность.
...


а если так:

 
Код:
double (&c)[10];

:)


to 3D Bob
может...
299
28 августа 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by dosER
а если так:
 
Код:
double (&c)[10];


Массив ссылок;)

11K
28 августа 2005 года
dosER
17 / / 04.07.2005
Цитата:
Originally posted by 3D Bob
Массив ссылок;)



тогда это что?

 
Код:
double &c[10];
:);)

3
28 августа 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by dosER
а если так:
 
Код:
double (&c)[10];

:)


Хм... твоя взяла! :)
Это действительно ссылка на массив.

Тогда конкретизируем код

 
Код:
template<int N>
X::X(int a, int b, double(&c)[N]); // определяем, что это будет ссылка на массив double, но размерность пока неизвестна
299
28 августа 2005 года
3D Bob
885 / / 18.04.2005
Да уж классно. Я просто думал нельзя, поэтому и ответил так))) Респект.
11K
28 августа 2005 года
dosER
17 / / 04.07.2005
Цитата:
Originally posted by Green
Хм... твоя взяла! :)
Это действительно ссылка на массив.

Тогда конкретизируем код
 
Код:
template<int N>
X::X(int a, int b, double(&c)[N]); // определяем, что это будет ссылка на массив double, но размерность пока неизвестна



все равно, ему ведь надо было размер массива узнать, я так понял, количесво элементов туда записанных(не максимально доступное количство).
к чему я клоню: он ведь память под него где-то выделял, значит, знает его размерность, а сколько элементов он туда поместил отсюда не выудишь. нужен счетчик, а следовательно, нет
смысла "передавать весь массив", как аргумент, достаточно только передавать значение счетчика.
Или можно использовать динамический массив, если ему значения элементов изменить потребуется.... решений много - как программистов:)

P.S. а шаблоны здесь не к месту, на мой взгляд

7.6K
28 августа 2005 года
Helicopterr
50 / / 21.08.2005
Цитата:
Originally posted by sergmagic
Почему, передавая массив в функцию-член, sizeof(этот массив) возвращает неверное значение?(C++)


в теле функции опер sizeof не сможет правильно определить размер параметра т.к. ф-ция получает только адрес первого элемента массива, поэтому опер вернёт размер этого адреса а не самого массива.

991
01 сентября 2005 года
Zenhipster
157 / / 14.01.2005
Цитата:
Originally posted by sergmagic
X::X(int a,int b,double c[])
{
if((a*b)!=sizeof(c)) error("Fuck");
...
}
Все время выдает ошибку(Fuck), хотя a=4 b=4 c[16]={1,2,..,16} к примеру.



IMHO лучше всего описать класс "надежный массив", или связным списком воспользоваться, если задача того позволяет... Надежные массивы описаны в любой книге по структурам данных C++.

То Green:
А я вот то же частенько матерюсь в исходниках =))

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог