Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[34.231.180.210] |
|
Сообщ.
#1
,
|
|
|
вопрос
void do_(int d[4] = {}) { printf("%d",sizeof d); } тут выводит 8 независимо от размера. но main(){ int df[40]; printf("%d", sizeof df); } а вот тут 160 почему? |
Сообщ.
#2
,
|
|
|
Потому что массивы по значению никогда не передаются. Всегда по указателю на первый элемент. Это сбивает с толку, да, потому как размер массива просто игнорируется, как будто бы там пусто:
void do_(int d[] = {}) void do_(int *d = {}) Но ты можешь передать ссылку на массив: int init_d[] = {1,2,3,4}; void do_(int (&d)[4] = init_d) |
Сообщ.
#3
,
|
|
|
в первом случае размер указателя
но во втором массива. а в чем смысл передавать ссылку на массив если массив передается по указателю? или получается это единственный способ узнать размер стат массива template<size_t n=4> void do_(int (&d)[n]) |
Сообщ.
#4
,
|
|
|
Смысл в отсутствии сведения массива к указателю. Обычно такое сведение не мешает, но если мешает, то да, передать по ссылке можно, при этом размер массива выводится в точке вызова и сохраняется в типе параметра. Затем можно передать в обобщённую функцию:
void do_impl(int *d, size_t n); template<size_t N> void do_(int (&d)[N]) { do_impl(d, N); } Добавлено P.S. Ссылки на массивы не сводятся, сводятся только непосредственно массивы. И это не будет работать с динамическими, для которых размер при компиляции не известен. Добавлено P.P.S. Также имеет смысл посмотреть в сторону стандартного контейнера std::array<>: void do_(std::array<int, 4> d) { /* ... */ } Добавлено А вместо динамических массивов std::vector<>, его тоже можно по значению, если приспичит. Оба контейнера имеют метод size(), владеют своими элементами, знают, когда их копировать/разрушать, сами управляют памятью под них, могут при желании следить за корректностью индексации, т.е. никаких ошибок с памятью. Настоятельно не рекомендую в Плюсах использовать Cшные привычки. |