Я предполагаю, что int f(int[] a, int[] b)
является опечаткой: оно должно быть int f(int a[], int b[])
.
Прежде всего, массивы и указатели отличаются . При многих обстоятельствах имя массива «распадается» на указатель на его первый элемент, но не всегда. В противном случае sizeof a
для массива a
не будет работать.
Во-вторых, давайте на минуту проигнорируем рекурсию. Давайте также упростим прототип функции:
int g(int *a);
(я изменил int a[]
на int *a
, потому что в этом контексте имя массива эквивалентно указателю.)
Теперь вы говорите, что можете «динамически размещать или изменять размер» массива в вызове функции. Поскольку все передается по значению в C , динамическое выделение или изменение размера a
внутри g()
не может быть видимым вызывающей стороной: вызывающая сторона все равно будет иметь старое значение a
. Но что более важно, если «оригинальный» тип a
был массивом, то есть вызывающий код имел такой код:
int data[SIZE];
g(data);
тогда попытка изменить размер data
в g()
плохая, потому что параметр, указанный в вызове, не был динамически выделен для начала. Вы можете только динамически изменить размер чего-либо, что было результатом malloc()
, calloc()
или realloc()
.
Итак, есть две проблемы даже с этим простым определением:
- Если
g()
должен динамически изменять размер памяти, на которую указывает адрес, который ему дан, значение должно быть получено из динамического выделения, а не массива,
- После исправления этого, так как
g()
хочет иметь возможность сигнализировать об изменении вызывающей стороне, вам нужно передать указатель на то, что необходимо изменить. Итак, прототип g()
становится: int g(int **a);
.
Надеюсь, вышеизложенное поможет вам начать. Если вы расскажете нам больше о своем алгоритме, в частности о том, что вы подразумеваете под «изменением» и «написанием», вы получите лучшие ответы.
Редактировать : ответить на ваш вопрос в комментарии:
Поэтому, когда я передал массив функции, он распадается на указатель, и этот указатель передается по значению. Если этот указатель указывает место, которое я выделил перед этим вызовом ...
Если вы выделили что-то до вызова, он никогда не был массивом для начала. Он может быть проиндексирован как массив, но это не главное. Так что, может быть, вас здесь смущает терминология?
... когда моя новая функция меняет указанное значение, то это значение изменяется и у вызывающего абонента.
Указанное значение изменено, да.
Я не хочу, чтобы это было так, поэтому мне нужна копия указанного значения в новой функции, чтобы неизмененное значение моего исходного указателя не изменилось. теперь я ясно?
Теперь стало понятнее, но тогда возникает больше вопросов:
- Если вы собираетесь динамически размещать или изменять размер данных при каждом вызове функции, как вы собираетесь возвращать эти новые указатели? Ты не можешь А это значит, что у тебя утечка памяти. Если только вы не
free()
данные в самой (рекурсивно вызванной) функции.
- Как бы вы изменили размер указателя? Возможно, вам не удастся узнать размер указанных данных, если вы не используете значение часового.
Вы используете функцию для итеративного решения головоломки или проблемы? Вы free()
вводите свои данные при каждом вызове функции? Если вы можете сказать нам, что именно вы пытаетесь сделать?