Что такое ссылка вперед в C?

Сумма первых цифр

Функция

Function SFD(Range As Range) As Long
    Dim vnt As Variant, i As Long, j As Long
    vnt = Range
    For i = 1 To UBound(vnt)
        For j = 1 To UBound(vnt, 2)
            If IsNumeric(vnt(i, j)) Then
                If CLng(vnt(i, j)) > 0 Then SFD = SFD + CLng(Left(vnt(i, j), 1))
            End If
        Next
    Next
End Function

В ячейке C9 используется формула: =SFD(B5:G5).

Версия массива

Sub SumOfFirstDigit()

    Const cRow As Long = 5
    Const cCol1 As Variant = 2
    Const cCol2 As Variant = 7
    Const cTarget As String = "C9"

    Dim j As Long
    Dim sumFirst As Long
    Dim vnt As Variant

    vnt = Range(Cells(cRow, cCol1), Cells(cRow, cCol2))

    For j = 1 To UBound(vnt, 2)
        If IsNumeric(vnt(1, j)) Then
            If CLng(vnt(1, j)) > 0 Then _
                    sumFirst = sumFirst + CLng(Left(vnt(1, j), 1))
        End If
    Next

    Range(cTarget).Value = sumFirst

End Sub

Версия диапазона

Sub SumOfFirstDigit2()

    Const cRow As Long = 5
    Const cCol1 As Variant = 2
    Const cCol2 As Variant = 7
    Const cTarget As String = "C9"

    Dim j As Long
    Dim sumFirst As Long

    For j = cCol1 To cCol2
        If IsNumeric(Cells(cRow, j)) Then
            If Cells(cRow, j) > 0 Then _
                    sumFirst = sumFirst + CLng(Left(Cells(cRow, j), 1))
        End If
    Next

    Range(cTarget).Value = sumFirst

End Sub

Быстрый ремонт

  • Вы забыли Dim cellref As Range.
  • Вы забыли Set в Set cellref = Cells(5, colnum).
  • Вы ошиблись celref в sumfirst = sumfirst + (Left(cellref, 1)).
  • Вы забыли Set cellref = Nothing
  • Integer мертв , Long преобладает.

Код

Sub sum_first_digit()

    Dim cellref As Range
    Dim colnum As Long
    Dim sumfirst As Long

    sumfirst = 0

    For colnum = 2 To 7
        Set cellref = Cells(5, colnum)
        sumfirst = sumfirst + (Left(cellref, 1))
    Next colnum

    Range("C9").Value = sumfirst

    Set cellref = Nothing

End Sub
6
задан Jonathan Leffler 28 November 2008 в 20:12
поделиться

6 ответов

Посмотрите эту страницу на ссылках вперед. Я не вижу, как вперед ссылка отличалась бы с указателями и с другими типами PoD.

Обратите внимание, что можно передать, объявляют типы и объявляют переменные, которые являются указателями на тот тип:

struct MyStruct;
struct MyStruct *ptr;
struct MyStruct var;  // ILLEGAL
ptr->member;  // ILLEGAL

struct MyStruct {
    // ...
};

// Or:

typedef struct MyStruct MyStruct;
MyStruct *ptr;
MyStruct var;  // ILLEGAL
ptr->member;  // ILLEGAL

struct MyStruct {
    // ...
};

Я думаю, что это - то, что Вы просите при контакте с указателями и предописанием.

11
ответ дан 8 December 2019 в 04:56
поделиться

Я думаю, что "ссылка вперед" относительно указателей означает что-то вроде этого:

struct MyStruct *ptr; // this is a forward reference.

struct MyStruct
{
  struct MyStruct *next; // another forward reference - this is much more useful
  // some data members
};

Указатель объявляется, прежде чем структура, на которую он указывает, определяется.

Компилятору может сойти с рук это, потому что указатель хранит адрес, и Вы не должны знать то, что в том адресе, чтобы зарезервировать память для указателя.

8
ответ дан 8 December 2019 в 04:56
поделиться

Ссылка вперед - когда Вы объявляете тип, но не определяете его.

Это позволяет Вам использовать тип указателем (или ссылка для C++), но Вы не можете объявить переменную.

Это - способ сказать компилятору, что что-то существует

Скажите, что Вам определили структуру Булькания в Plop.h:

struct Plop
{
   int n;
   float f;
};

Теперь Вы хотите добавить некоторые служебные функции, который работает с той структурой. Вы создаете другой файл PlopUtils.h (скажем, Вы не можете изменить Plop.h):

struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time

void doSomething(Plop* plop);
void doNothing(Plop* plop);

Теперь, когда Вы реализуете, они функционируют, Вам будет нужно определение структуры, таким образом, необходимо будет включать файл Plop.h в PlopUtils.cpp:

#include "PlopUtils.h"
#include "Plop.h" // now we need to include the header in order to work with the type

void doSomething(Plop* plop)
{
   plop->n ...
}

void doNothing(Plop* plop);
{
   plop->f ...
}
5
ответ дан 8 December 2019 в 04:56
поделиться

Добавление к предыдущим ответам. Типичная ситуация, в которой ссылка вперед обязательна, состоит в том, когда нечто структуры содержит указатель на панель структуры, и панель содержит указатель на нечто (круговая зависимость между объявлениями). Единственный способ выразить эту ситуацию в C состоит в том, чтобы использовать предописание, т.е.:

struct foo;

struct bar
{
   struct foo *f;
};

struct foo
{
   struct bar *b;
};
2
ответ дан 8 December 2019 в 04:56
поделиться

Я думаю, что компилятор C первоначально имел передачу, в которой он сделал здание таблицы символов и семантический анализ вместе. Так, например:

    ....
    ... foo(a,b) + 1 ... // assumes foo returns int
    ....

    double foo(double x, double y){ ... } // violates earlier assumption

для предотвращения этого Вы говорите:

    double foo(double x, double y); // this is the forward declaration

    ....
    ... foo(a,b) + 1 ... // correct assumptions made
    ....

    double foo(double x, double y){ ... } // this is the real declaration

Паскаль имел то же понятие.

3
ответ дан 8 December 2019 в 04:56
поделиться

Ссылки вперед позволяют компилятору C делать меньше передач, и значительно уменьшает время компиляции. Это, вероятно, был важен приблизительно 20 лет назад, когда компьютеры были намного медленнее и менее эффективные компиляторы.

-5
ответ дан 8 December 2019 в 04:56
поделиться
Другие вопросы по тегам:

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