ГДЕ x В (5), по сравнению с ГДЕ x = 5 …, почему использование В?

Ваш конструктор выделяет массив очень хорошо (хотя убедитесь, что остальная часть вашего класса правильно реализует правило 3/5/0 ), но он не заполняет массив какими-либо начальными значениями .

Ваш insert(), с другой стороны, имеет несколько проблем:

  • он проходит через 1 слишком много элементов. Массивы имеют индекс 0, что означает, что допустимыми индексами будут 0..sz-1, поэтому вам нужно использовать < вместо <= в цикле.

  • elts[i]; на самом деле не делает ничего значимого. Он просто читает значение из массива (в случае, когда значение i совпадает со значением numElts, оно будет считываться после конца массива в окружающую память), но оно ничего не делает с этим значением.

  • if (i = position) присваивает значение position i, а затем оценивает результат этого назначения (новое значение i) как логическое выражение. Таким образом, если position равно 0, то ничего не происходит вообще, поскольку 0 оценивается как ложное, но любое другое значение будет оцениваться как истина, и каждая итерация цикла (включая упомянутое выше 1 ошибочное значение) будет назначать value указанному индексу массива по position, который сам может выйти за пределы массива, поскольку вы его не проверяете. Чтобы сравнить исходное значение i как есть со значением position, вам нужно использовать операцию сравнения == вместо оператора присваивания =.

Вместо этого попробуйте что-то вроде этого:

Sequence::Sequence(size_type sz)
{
    numElts = sz;
    elts = new int[sz];
    // or: elts = new int[sz]();

    for (size_type i = 0; i < sz; ++i) {
        elts[i] = 0;
    }
    // or: std::fill(elts, elts + sz, 0);
    // or: std::fill_n(elts, sz, 0);
}

void Sequence::insert(size_type position, value_type value)
{
    for (size_type i = 0; i < numElts; ++i) {
        if (i == position) {
            elts[i] = value;
            break;
        }
    }
}

Однако, insert() можно значительно упростить, удалив цикл полностью:

void Sequence::insert(size_type position, value_type value)
{
    // NOTE: checking for '>= 0' can be skipped if size_type is unsigned ...
    if ((position >= 0) && (position < numElts)) {
        elts[position] = value;
    } 
}

6
задан Kip 15 May 2009 в 15:40
поделиться

9 ответов

Здесь нет никаких приемов для повышения производительности, но я не думаю, что это приведет к снижению производительности. Так что оба пути допустимы. Я согласен с вами в том, что использование предложения IN только с одним параметром выглядит забавно, но за ним все еще достаточно легко следить.

Я думаю, что это, вероятно, происходит потому, что разработчик считает, что в будущем возможно использование нескольких значений (это так, чтобы запрос не изменился). Или, возможно, разработчик привык к сценариям, в которых возможны несколько значений, и он просто написал так по привычке.

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

Может быть, неизвестно, относится ли $ visibility к одному или нескольким значениям? Не совсем подходит вашему примеру, но я видел такое использование в других местах.

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

Тогда WHERE x IN (1,2,3) - лучшая альтернатива WHERE x = 1 OR x = 2 ИЛИ x = 3 , верно? Но, конечно же, это единственный сценарий, в котором вы должны использовать IN ?

Нет, вы также можете использовать IN с подзапросом.

... где поле в (выберите поле из another_table)

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

Возможно, $ visibility генерируется динамически, например:

$visibility = implode(', ', array_map('intval', array(1, 2, 3)));

Где массив (1, 2, 3) может поступать из ненадежных источников.

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

In действует для любого типа операции над набором, тогда как = действует для одного значения. Таким образом, вы можете использовать in для нескольких записей в другой таблице или для любой другой структуры данных, представляющей несколько значений.

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

Я думаю, более конкретно, чтобы понять, что делает IN.

Если вы это сделаете

SELECT * FROM pages WHERE is_visible = $visibility

В приведенном выше примере $ visibility должна быть var, поэтому is_visibile = 1, так что ваш SQL собирает все, где is_visible = 1

Где

SELECT * FROM pages WHERE is_visible IN ($visibility)

$ visibility будет массивом данных, подобным тому, что проиллюстрировал Стэн @Ionut G.

Итак, ваш вызов будет выглядеть как is_visible IN ('1', '2' , '3')

Итак, теперь ваш SQL будет собирать все строки 1,2 и 3.

Надеюсь, что это имеет смысл. Это большая разница.

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

Нет, это не уловка. Два утверждения:

SELECT * FROM pages WHERE is_visible IN ($visibility)
SELECT * FROM pages WHERE is_visible = $visibility

почти эквивалентны. Заметим, что эти два утверждения эквивалентны в тривиальном случае, например, когда $ visibility является скаляром со значением 1.

Но утверждения не эквивалентны в нетривиальные случаи, когда $ visibility содержит что-то еще. Мы можем наблюдать значительную разницу в поведении двух форм. Рассмотрим, что происходит с каждой формой, когда $ visibility представляет собой строку, содержащую следующие примерные значения:

    '1,2,3' 
    '1 OR 1=1'
    'select v.val from vals v'

Мы наблюдаем значительную разницу в результирующих операторах SQL, сгенерированных из двух форм:

    SELECT * FROM pages WHERE is_visible IN (1,2,3)
    SELECT * FROM pages WHERE is_visible = 1,2,3
    SELECT * FROM pages WHERE is_visible IN (1 OR 1=1 )
    SELECT * FROM pages WHERE is_visible = 1 OR 1=1

Здесь большое беспокойство, с любой формой оператора - это возможность SQL-инъекции. Если $ visibility задуман как скалярное значение, тогда использование переменной связывания в операторе является более безопасным подходом, поскольку он позволяет избежать вставки «лишнего» синтаксиса SQL в оператор. (Конечно, использование переменных связывания не предотвращает всех SQL-инъекций, но это подходящий подход для закрытия одной дыры. Использование переменной связывания также улучшит масштабируемость, по крайней мере, на некоторых платформах СУБД, таких как Oracle.)

Подумайте, что происходит, когда мы используем связываемую переменную (заполнитель), которая, как мы знаем, не будет НЕ интерпретироваться как синтаксис SQL. Мы замечаем, что два оператора ЯВЛЯЮТСЯ действительно эквивалентными:

    SELECT * FROM pages WHERE is_visible IN ( ? )
    SELECT * FROM pages WHERE is_visible = ? 

для любого значения, предоставленного для переменной связывания.

HTH

t предотвратить все SQL-инъекции, но это подходящий подход к закрытию одной дыры. Использование переменной связывания также улучшит масштабируемость, по крайней мере, на некоторых платформах СУБД, таких как Oracle.)

Подумайте, что происходит, когда мы используем переменную связывания (заполнитель), которая, как мы знаем, НЕ будет интерпретироваться как Синтаксис SQL. Мы замечаем, что два оператора ЯВЛЯЮТСЯ действительно эквивалентными:

    SELECT * FROM pages WHERE is_visible IN ( ? )
    SELECT * FROM pages WHERE is_visible = ? 

для любого значения, предоставленного для переменной связывания.

HTH

t предотвратить все SQL-инъекции, но это подходящий подход к закрытию одной дыры. Использование переменной связывания также улучшит масштабируемость, по крайней мере, на некоторых платформах СУБД, таких как Oracle.)

Подумайте, что происходит, когда мы используем переменную связывания (заполнитель), которая, как мы знаем, НЕ будет интерпретироваться как Синтаксис SQL. Мы замечаем, что два оператора ЯВЛЯЮТСЯ действительно эквивалентными:

    SELECT * FROM pages WHERE is_visible IN ( ? )
    SELECT * FROM pages WHERE is_visible = ? 

для любого значения, предоставленного для переменной связывания.

HTH

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

«WHERE x IN (1,2,3)» в любом случае совпадает с «WHERE x = 1 OR x = 2 OR x = 3».

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

Затем WHERE x IN (1,2, альтернатива WHERE x = 1 OR x = 2 OR х = 3, верно? Но наверняка это единственный сценарий, в котором вы должны использовать IN?

IN () и OR синтаксически эквивалентны. Это покажет изучение плана выполнения ваших двух предложений. IN () - это просто более эффективная и легкая для понимания запись.

0
ответ дан 8 December 2019 в 03:11
поделиться
Другие вопросы по тегам:

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