Когда использовать экстерна “C” в C++? [дубликат]

Короткое объяснение:

, Если алгоритм имеет О ˜ (g (n)), это означает, что время выполнения алгоритма как n (входной размер) становится больше, пропорционально g (n).

, Если алгоритм имеет O (g (n)), это означает, что время выполнения алгоритма как n становится больше, самое большее пропорциональны g (n).

Обычно, даже когда люди говорят о O (g (n)) они на самом деле имеют в виду О ˜ (g (n)), но технически, существует различие.

более технически:

O (n) представляет верхнюю границу. О ˜ (n) означает трудный связанный. О© (n) представляет нижнюю границу.

f (x) = О ˜ (g (x)) эквивалентность f (x) = O (g (x)) и f (x) = О© (g (x))

В основном, когда мы говорим, что алгоритм имеет O (n), это также O (n 2 глоток>), O (n 1000000 глоток>), O (2 n глоток>)... но О ˜ (n) алгоритм не О ˜ (n 2 глоток>).

На самом деле, с тех пор f (n) = О ˜ (g (n)) средства для достаточно больших значений n, f (n) могут быть связаны в c1 г (n) и c2 г (n) для некоторых значений c1 и c2, т.е. темп роста f асимптотически равен g: g может быть нижней границей и и верхняя граница f. Это непосредственно подразумевает, что f может быть нижней границей и верхней границей g также. Следовательно,

f (x) = О ˜ (g (x)) эквивалентность g (x) = О ˜ (f (x))

Точно так же для показа f (n) = О ˜ (g (n)) достаточно показать, что g является верхней границей f (т.е. f (n) = O (g (n))), и f является нижней границей g (т.е. f (n) = О© (g (n)), который является той же самой вещью как g (n) = O (f (n))). Кратко,

f (x) = О ˜ (g (x)) эквивалентность f (x) = O (g (x)) и g (x) = O (f (x))

существует также, мало-о, и мало-омега (ω) нотации, представляющие свободные верхние и свободные нижние границы функции.

Для суммирования:

f(x) = O(g(x)) (большой об) означает, что темп роста f(x) асимптотически меньше чем или равен [1 118] к темпу роста g(x).

f(x) = Ω(g(x)) (большая омега) означает, что темп роста f(x) асимптотически больше, чем или равный [1 119] темп роста g(x)

f(x) = o(g(x)) (мало-о), средства, что темп роста f(x) асимптотически меньше чем [1 120] темп роста g(x).

f(x) = ω(g(x)) (мало-омега) означает, что темп роста [1 111] асимптотически больше, чем [1 121], темп роста [1 112]

f(x) = Θ(g(x)) (тета) означает, что темп роста [1 114] асимптотически равен [1 122] темп роста [1 115]

Для более детального обсуждения, Вы можете читать определение на Википедию или консультироваться с классическим учебником как Введение в Алгоритмы Cormen и др.

22
задан 8 revs, 3 users 50%unknown 23 May 2017 в 12:34
поделиться

2 ответа

extern «C» делает имена неискаженными.

Используется, когда:

  1. Нам нужно использовать некоторую библиотеку C в C ++

     extern «C» int foo (int) ;
    
  2. Нам нужно экспортировать некоторый код C ++ в C

     extern «C» int foo (int) {something; }
    
  3. Нам нужна возможность разрешать символы в разделяемой библиотеке - поэтому нам нужно избавиться от искажения

     extern "C" int foo (int) {something; }
    ///
    typedef int (* foo_type) (интервал);
    foo_type f = (foo_type) dlsym (дескриптор, "foo")
    
32
ответ дан 29 November 2019 в 04:26
поделиться

Одно из мест, где extern "C" имеет смысл, - это когда вы связываетесь с библиотекой, которая была скомпилирована как код C.

extern "C" {
  #include "c_only_header.h"
}

В противном случае вы можете получить ошибки компоновщика, потому что библиотека содержит функции с C-компоновкой (_myfunc), но компилятор C ++, который обработал заголовок библиотеки как код C ++, сгенерировал имена символов C ++ для функций (" _myfunc @ XAZZYE"- это называется искажением и отличается для каждого компилятора).

Другое место, где используется extern" C ", - это гарантия связывания C даже для функций, написанных на C ++, например.

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}

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

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}
extern "C" void __stdcall PrintHello(const char *name) {
  cout << "Hello, " << name << endl;
}

Большинство компиляторов перехватили бы это и, таким образом, предотвратили бы использование перегрузок функций в вашем DLL-общедоступные функции.

14
ответ дан 29 November 2019 в 04:26
поделиться