powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си и массив как аргумент функции
25 сообщений из 505, страница 1 из 21
Си и массив как аргумент функции
    #39957510
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут пришлось с Си (не С++) поработать. Правильно ли, что вот это вот для компилятора эквивалентно?

Код: plaintext
1.
2.
void foo(int a[3]);
void foo(int *a);


Т.е. первая функция на самом деле видится компилятором как вторая? И по сути "int a[3]" только человек может прочитать, а компилятор тут видит "int *a"?
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957551
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

не верно:
в первом случае вы передаете целое число а[3] (из некоторого массива а)
во втором показатель на целое число

по-видимому, в первом случае вы имели ввиду int a[], тогда имело бы смысл говорить об эквивалентности.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957556
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я-бы рассмотрел еще многомерные. И varrargs.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957562
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab

в первом случае вы передаете целое число а[3] (из некоторого массива а)
во втором показатель на целое число

Чё?

mini.weblab
по-видимому, в первом случае вы имели ввиду int a[]

Нет.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957570
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab
petrav,
void foo(int a[3]);
в первом случае вы передаете целое число а[3] (из некоторого массива а)
.

здесь я неправа,

в мануале передают массив так
void foo(int *а);
void foo(int a[]);
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957585
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Т.е. первая функция на самом деле видится компилятором как вторая? И по сути "int a[3]" только человек может прочитать, а компилятор тут видит "int *a"?

Да.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957598
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,
1.
я думаю, что все зависит от реализации конкретного компилятора

2.
по Кернигану-Ричи, когда речь идет о массиве, все три выражения эквивалентны
авторParameter declaration:
So as far as f is concerned, the fact that the parameter refers to part of a larger array is of no consequence.
...
Of course, it is illegal to refer to objects that are not within the array bounds.

f - обозначение декларируемой функции: f(int *arr), f(int arr[])


Код: plaintext
1.
2.
3.
void foo(int a[]);
void foo(int a[3]);
void foo(int *a);



3.
В общем случае выражения не будут эквивалентными, т.к. выражении void foo(int *a) будет более общим,
как доказательство предложу рассмотреть отсутствие ограничения на количество элементов массива
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957602
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab


Код: plaintext
1.
2.
3.
void foo(int a[]);
void foo(int a[3]);
void foo(int *a);



3.
В общем случае выражения не будут эквивалентными, т.к. выражении void foo(int *a) будет более общим,
как доказательство предложу рассмотреть отсутствие ограничения на количество элементов массива

Ну вот у меня в Студии (компилятор Си) в функцию "void foo(int a[3])" подставляется и NULL, и массив из 5-ти элементов, и простой указатель на int. И всё без единого варнинга. Во язык, я понимаю. :) Простой и ясный.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957611
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
mini.weblab


Код: plaintext
1.
2.
3.
void foo(int a[]);
void foo(int a[3]);
void foo(int *a);



3.
В общем случае выражения не будут эквивалентными, т.к. выражении void foo(int *a) будет более общим,
как доказательство предложу рассмотреть отсутствие ограничения на количество элементов массива

Ну вот у меня в Студии (компилятор Си) в функцию "void foo(int a[3])" подставляется и NULL, и массив из 5-ти элементов, и простой указатель на int. И всё без единого варнинга. Во язык, я понимаю. :) Простой и ясный.

Это то о чем я говорил. Чортов компиллятор может 80% потенциальных граблей отбросить без этих ПВС-студий
еще в фазе компилляции.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957621
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЧортов компиллятор может 80% потенциальных граблей отбросить без этих ПВС-студий
еще в фазе компилляции.

Может. Но не хочет. Вместо этого почему-то подменяет написанное "передать массив трёх
целых по значению" на "передать указатель на любой массив".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957629
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

maytonЧортов компиллятор может 80% потенциальных граблей отбросить без этих ПВС-студий
еще в фазе компилляции.

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

Потому что так в стандарте написано. Я вспомнил, где-то читал, то ли у Керниган & Ритчи, то ли у Страуструпа, что вот такое "int a[3]" в сигнатуре функции -- это просто подсказка для человека. Но на самом деле там "int *a". Компилятор тут бессилен. Он даже варнинг тут выдать не может.

А массивы в Си не передаются по значению и тоже по стандарту. Хотя это косяк из-за не симметрии. Структуры же передаются по значению. У них была странная аргументация: массивы не передаются по значению, что бы из-за ошибки программиста не просадить производительность приложения.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957630
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
:)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
#include <stdio.h>

void print_arr(int arr[3]) {
    for (int i=0; i<1000; i++) {
        printf("%d, %d\n", i, arr[i]);
    }
}

void main() {
    int arr[] = {0};
    int *a;
    a = &arr[0];
    print_arr(arr);
    for (int i=0; i<1000; i++) {
        printf("%d, %d\n", i, *(a+i));
    }
    printf("\n");
}
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957666
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Ну вот у меня в Студии ... И всё без единого варнинга. Во язык, я понимаю. :) Простой и ясный.

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

По теме: массив и указатель одно и тоже, передать массив в параметрах нельзя, но передавая массив как указатель размер массива не передается. В шаблонах С++ можно передать массив как массив, но тогда для каждой размерности массива компилируется отдельная функция.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957670
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#include <stdio.h>

void main() {
    int arr[] = {0, 1, 2, 3, 4, 5};
    int *a;
    a = arr;
    int size_of_ptr_a = sizeof(a);
    int size_of_arr = sizeof(arr);

    printf("%d, %d\n", size_of_ptr_a, size_of_arr);
}
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957677
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
petrav
Ну вот у меня в Студии ... И всё без единого варнинга. Во язык, я понимаю. :) Простой и ясный.

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

Уровень предупреждений стоит на оптимальном значении -- 3. Выше начинают сыпаться предупреждения на сторонние библиотеки. Даже на Windows.h. Я не знаю как их отфильтровать.

Dima T
По теме: массив и указатель одно и тоже, передать массив в параметрах нельзя, но передавая массив как указатель размер массива не передается. В шаблонах С++ можно передать массив как массив, но тогда для каждой размерности массива компилируется отдельная функция.

Тут другое хуже. Вот так может быть только в заголовочных файлах (исключая вариант если шаблонный метод вызывается только внутри реализации класса):

Код: plaintext
1.
2.
template <size_t N>
void foo(int (&a)[N]) {}


А external templates они так и не реализовали почему-то. Вот что мешало?
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957680
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
А external templates они так и не реализовали почему-то. Вот что мешало?

Такие шаблоны сами по себе зло.

Не надо путать массивы С с массивами С# или Java. Аналог в C++ тех массивов класс std::vector, используй его.

Если хочется передать именно массив С, то передаешь указатель и размер, т.е.
Код: plaintext
1.
void foo(int *a, size_t size);
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957685
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
А external templates они так и не реализовали почему-то. Вот что мешало?

А мешало то что под каждый размер компилируется отдельная функция, как ты представляешь заранее скомпилировать size_t функций? Для x64 size_t это 2 64
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957687
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void test_arr() {
    int arr[3] = {1,2,3};
    int n = 10000;

    for ( int i=0; i<n; i++ ) {
        printf("%d, %p, %d\n", i, &arr[i],  arr[i]);
        printf("\n");
    }
}

void test_ptr() {
    int n = 10000;
    int *a;
    *a = 0;

    for ( int i=0; i<n; i++ ) {
        printf("%d, %p, %d\n", i, a+i,  *(a+i));
        printf("\n");
    }
}
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957688
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
petrav
А external templates они так и не реализовали почему-то. Вот что мешало?

Такие шаблоны сами по себе зло.

Какие такие? External templates зло? Почему?

Dima T
Не надо их путать массивы С с массивами С# или Java. Аналог в C++ тех массивов класс std::vector, используй его.

Если хочется передать именно массив С, то передаешь указатель и размер, т.е.
Код: plaintext
1.
void foo(int *a, size_t size);


Да я это понимаю. Я вопрос задал для очистки совести. Вдруг совершенно неожиданно тут "void foo(int a[3])" я догадался, что "a == NULL" вполне реально. Поскольку я программирую на С++ были необычные ощущения.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957689
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

хватит откровенный бред постить.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957695
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Какие такие? External templates зло? Почему?

Про External 22133213 , а зло потому что под каждый размер скомпилируется отдельная функция. Сто вызовов с разным размером - в конечном коде будет 100 разных функций. 1000 - 1000. И задать размер массива можно только явно до компиляции.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957698
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
petrav
А external templates они так и не реализовали почему-то. Вот что мешало?

А мешало то что под каждый размер компилируется отдельная функция, как ты представляешь заранее скомпилировать size_t функций? Для x64 size_t это 2 64

А как ты себе представляешь в программе руками набить 2 64 массивов:

Код: plaintext
1.
2.
char a1[1];
char a1[2];


Что бы для них скомпилировалось 2 64 шаблонов? Только написав кодогенератор что бы сломать компилятор.

И главное, при чём тут external template?!
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957702
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
petrav
Какие такие? External templates зло? Почему?

Про External 22133213 , а зло потому что под каждый размер скомпилируется отдельная функция. Сто вызовов с разным размером - в конечном коде будет 100 разных функций. 1000 - 1000. И задать размер массива можно только явно до компиляции.

Где тут размер массива?

Код: plaintext
1.
2.
external template <typename Char>
void drawMyChar(Char);


Может я что-то путаю?
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957705
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
И главное, при чём тут external template?!

external это значит скомпилировать заранее, например DLL. Как скомпилировать DLL не зная что вызовут?
Код: plaintext
1.
2.
3.
4.
int a1[5] = ...;
foo(a1);
int a2[100500] = ...;
foo(a2);


Если foo() internal, т.е. код шаблона в .h файле, то будет скомпилировано две функции, а если external то надо заранее иметь все возможные варианты.
...
Рейтинг: 0 / 0
Си и массив как аргумент функции
    #39957708
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
... массив и указатель одно и тоже.

неверно! это не бред, это контрпример!
mini.weblab
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#include <stdio.h>

void main() {
    int arr[] = {0, 1, 2, 3, 4, 5};
    int *a;
    a = arr;
    int size_of_ptr_a = sizeof(a);
    int size_of_arr = sizeof(arr);

    printf("%d, %d\n", size_of_ptr_a, size_of_arr);
}

...
Рейтинг: 0 / 0
25 сообщений из 505, страница 1 из 21
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си и массив как аргумент функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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