Передача указателей / ссылок на структуры в функции

13
задан Don Kirkby 17 November 2008 в 05:03
поделиться

6 ответов

я думаю, что Вы хотите сделать, это:

void canonRect(struct rect *r) {
    struct rect temp;
    temp.lowerLeft.x = min(r->lowerLeft.x, r->upperRight.x);
    temp.lowerLeft.y = min(r->lowerLeft.y, r->upperRight.y);
    temp.upperRight.x = max(r->lowerLeft.x, r->upperRight.x);
    temp.upperRight.y = max(r->lowerLeft.y, r->upperRight.y);

    *r = temp; 
}

В вышеупомянутом коде Вы устанавливаете *r, который имеет тип, реагируют для временной работы, который имеет тип, реагируют.

Ре 1: Если Вы хотите изменить, какой r указывает на Вас, должен использовать указатель на указатель. Если это действительно, что Вы хотите (см. выше, это не действительно, что Вы хотите), тогда, необходимо было бы удостовериться, что указали на него на что-то на "куче". При указании на него на что-то не созданное с 'новым' или malloc тогда, это упадет из объема, и Вы будете указывать на память, которая больше не используется для той переменной.

, Почему не делает Вашего кода, работают с r = & временный файл?

, поскольку r имеет, реагируют* тип. Это означает, что r является переменной, которая содержит адрес памяти, кто память, содержит реагирование. Если Вы изменяете то, на что указывает r, это прекрасно, но это не изменяет переданный в переменной.

Ре 2: * если не используемый в описании типа разыменовать унарный оператор. Это означает, что будет поиск, что в адресе указателя. Таким образом путем передачи *r Вы не передают указатель вообще. В поверхности, так как r не является указателем, который является недопустимым синтаксисом.

18
ответ дан Uli Köhler 17 November 2008 в 05:03
поделиться
  • 1
    sepp2k, да, моя ошибка. Я имел в виду невведенный, но braino' d. – luqui 7 April 2010 в 04:15

Во-первых, K& R c не имеет понятия "ссылок", просто указатели. & средства оператора "берут адрес".

<час>

, Во-вторых, r в cannonRect() локальная переменная и не r в main(). Изменение, где локальное r точки не производит r в вызывающей подпрограмме.

<час>

Наконец, как уже отмечено локальное struct rect выделяется на стеке и выходит в близкой фигурной скобке,

2
ответ дан dmckee 17 November 2008 в 05:03
поделиться
  • 1
    Кажется разумным. С другой стороны, компилятор Flash/Flex может быть удивительно глуп , поэтому как Вы говорите, I' d проверяют перед использованием этого, если производительность действительно имеет значение для Вас. – aaaidan 11 June 2010 в 02:42

Это кажется, что Вы путаете 'разыменовать' оператор (*) с 'адресом' оператора (&).

, Когда Вы пишете &r, который получает адрес r и возвращает указатель на r (указатель является просто адресом памяти переменной). Таким образом, Вы действительно передаете указатель в функцию.

, Когда Вы пишете *r, Вы пытаетесь разыменовать r. Если r является указателем, который возвратит значение, на которое указывает r. Но r не является указателем, это - реагирование, таким образом, Вы получите ошибку.

Для создания вещей более сбивающими с толку * символ также используется при объявлении переменных указателя. В этом объявлении функции:

void canonRect(struct rect *r) {

r, как объявляют, указатель на struct rect. Это полностью отличается от использования * как это:

canonRect(*r); 

В обоих случаях, * символ означает что-то совершенно другое.

5
ответ дан Jeremy Ruten 17 November 2008 в 05:03
поделиться

Который также стоит отметить Вашу переменную 'структуру rec временный файл', собирается выйти из объема, как только тот метод canonRect заканчивается, и Вы будете указывать на недопустимую память.

12
ответ дан Joel Cunningham 17 November 2008 в 05:03
поделиться
  • 1
    It' s стоящий добавления, что можно на самом деле встроить невведенное лямбда-исчисление в Agda путем оценки его в монаде пристрастия, который модели возможное незавершение с возможно бесконечным числом дискретных шагов. – copumpkin 26 April 2012 в 04:33

2. Почему я мог бы получить недопустимую косвенную ошибку времени компиляции, если я пытаюсь передать в указателе на canonRect? (IE, если у меня был canonRect (*r); в основном ()).

, поскольку, это не цель указатель .

-1
ответ дан plan9assembler 17 November 2008 в 05:03
поделиться
  • 1
    Да, я думаю, что эта техника полагается слишком много на побочный эффект оптимизатора. Условная компиляция намного лучше. При необходимости в чем-то как #ifndef см. мой ответ ниже. – Chris Hill 31 October 2012 в 22:59

Вы могли бы хотеть читать на различных способах, которыми параметры могут (концептуально) быть переданы функциям. C вызов по значению , поэтому при передаче указателя на реагирование в функцию, Вы передаете копию указателя. Любые изменения, которые функция вносит в значение r непосредственно (весьма непосредственно) не будут видимы вызывающей стороне.

, Если Вы хотите, чтобы функция предоставила вызывающей стороне новую структуру тогда, существует два способа сделать ее: 1. можно возвратить реагирование: 2. можно передать указатель на указатель на реагирование в:

первый путь был бы более естественным:

struct rect* canonRect(struct rect* r)
{
  struct rect* cr = (struct rect*) malloc(sizeof(struct rect));
  ...
  return cr;
}

второй путь был бы:

void canonRect(struct rect** r)
{
  *r = (struct rect*) malloc(sizeof(struct rect));
}

и вызывающая сторона тогда использовал бы:

   canonRect(&r);

, Но вызывающая сторона теряет исходный указатель, который это имело, и необходимо будет бояться пропускать структуры.

, Какой бы ни техника Вы используете, функция должна будет выделить память для новой структуры на "куче" с помощью malloc. Вы не можете выделить место на стеке, просто объявив структуру, потому что та память становится недопустимой, когда функция возвращается.

2
ответ дан Rob Walker 17 November 2008 в 05:03
поделиться
  • 1
    - 1. , если/еще конструкция doesn' t работа.. простой тест для доказательства его: [Встройте] тяжелый файл в такой если/еще блок. Если выходной размер файла изменяется соответственно тогда, он работает, иначе это doesn' t. Также такой, если/еще блок производит синтаксические ошибки, когда используется вне функции, которая приводит к заключению что блок кода won' t разделяется! – bummzack 6 July 2012 в 12:20
Другие вопросы по тегам:

Похожие вопросы: