C/C++

Материал из theor
Перейти к: навигация, поиск

Введение.

Язык программирования Си отличается минимализмом. Авторы языка хотели, чтобы программы на нём легко компилировались с помощью однопроходного компилятора, чтобы каждой элементарной составляющей программы после компиляции соответствовало весьма небольшое число машинных команд, а использование базовых элементов языка не задействовало библиотеку времени выполнения. Однопроходный компилятор компилирует программу, не возвращаясь назад, к уже обработанному тексту. Поэтому использованию функции и переменных должно предшествовать их объявление. Код на Си можно легко писать на низком уровне абстракции, почти как на ассемблере. Иногда Си называют «универсальным ассемблером» или «ассемблером высокого уровня», что отражает различие языков ассемблера для разных платформ и единство стандарта Си, код которого может быть скомпилирован без изменений практически на любой модели компьютера. Си часто называют языком среднего уровня или даже низкого уровня, учитывая то, как близко он работает к реальным устройствам. Однако, в строгой классификации, он является языком высокого уровня.

C++ в отличие от языка Си поддерживает такие парадигмы программирования как процедурное программирование, объектно-ориентированное программирование, обобщенное программирование, обеспечивает модульность, раздельную компиляцию, обработку исключений, абстракцию данных, объявление типов (классов) объектов, виртуальные функции. Стандартная библиотека включает, в том числе, общеупотребительные контейнеры и алгоритмы. C++ сочетает свойства как высокоуровневых, так и низкоуровневых языков. В сравнении с его предшественником — языком Си, — наибольшее внимание уделено поддержке объектно-ориентированного и обобщённого программирования.

Ссылки

Википедия

StackOverFlow

Хабр

Установка компилятора.

Мы будем использовать gcc для компиляции команд, написанных на C/C++. Он часто используется как стандартный компилятор в Linux/UNIX системах. Пользователи Windows, программирующие на Си могут использовать в своих целях среду разработки eclipse, и один из компиляторов (MinGW, Cygwin) на свое усмотрение. По поводу установки сюда:

Эклипс

Мы же будем использовать gcc в виду его удобства в связке с gedit (Archlinux) или sublime text (Mac OS X).

В линуксоподобных системах чаще всего gcc уже установлен, и им уже можно пользоваться. Либо же, при сборке системы стоит отметить пакет с gcc. Либо же, можно воспользоваться консолью.

ubuntu: sudo apt-get install gcc

archlinux: su pacman -S gcc

Archlinux

В Mac OS X все несколько прозаичнее, и для начала нужно установить саму консоль (например iTerm). Затем, нужен macports(сюда [1]). После того как вы справились с macports, нужно установить сам gcc. Открываем терминал и вводим:

 $ port select --list gcc
 Available versions for gcc:
   gcc42
   llvm-gcc42
   mp-gcc45
   none (active)

Например:

 $ sudo port select --set gcc gcc42
 Password:
 Selecting 'gcc42' for 'gcc' succeeded. 'gcc42' is now active.

Установка:

 sudo port install gcc42

Примечание: актуальная на сегодняшний день версия gcc - 4.7. Следовательно и ставить нужно gcc47.

Чтобы наконец оценить по достоинству работу с gcc, перейдем к следующему разделу.

Работа с GCC

Открываем любой текстовый редактор, например sublime text (он удобен, поскольку подсвечивает код), и пишем в нем программу следующего содержания: <source lang = "c">

 #include <stdio.h>
   int main(void)
 {
   printf("Hello, World.\n");
   return 0;
 }

</source> Сохраняем файл как hello.c

Открываем терминал, и с помощью cd и ls находим папку с файлом hello.c. Компилируем ее командой:

 gcc hello.c -o hello.out

Запускаем:

 ./hello.out

Результат:

 Hello, World.

Теперь разъясним по пунктам все действия.

В первой строке программы расположена директива препроцессора #include, встретив которую, компилятор заменяет её на полный текст файла, на который она ссылается. В данном случае эта строка будет заменена стандартным заголовочным файлом stdio.h. Угловые скобки указывают компилятору искать файл stdio.h в каталоге стандартных заголовочных файлов.

Следующая строка является объявлением функции с именем main. Эта функция в программе Си является особенной, так как выполняется первой из написанных программистом при запуске программы. Слово int говорит, что функция main возвращает целое число. Фигурные скобки после функции main обозначают её определение.

Следующая строка «вызывает» функцию printf. Включаемый заголовочный файл stdio.h содержит информацию, описывающую то, как нужно вызывать эту функцию. В данном примере этой функции передаётся единственный аргумент, содержащий текстовую строку "Hello, World!\n". Последовательность \n транслируется в символ «новая строка», который при отображении соответственно обозначает разрыв строки. Функция printf возвращает значение типа int, которое возвращает число напечатанных символов (в этом примере возвращаемое значение игнорируется).

Выражение return заставляет программу прекратить выполнение функции (main в этом случае), возвращая вызвавшей функции значение, указанное после ключевого слова return (здесь 0). Так как текущая функция — это main, то вызывающим является код, который и запустил программу. Последняя фигурная скобка обозначает конец определения функции main. По стандарту C99, return 0 в main не обязательно (отсутствие return в main означает return 0;).

Большая часть даже стандартных функций(типа функции вывода - printf) в Си находится в заголовочных файлах, которые нужно подключить.

Вернемся к gcc. Образно говоря, мы скормили компилятору какой то файл, и попросили его вывести результат (-o = output) в виде файла с расширением .out (такое расширение стандартно для исполняемых файлов в UNIX системах). Можно не писать -o, тогда компилятор создаст файл по умолчанию (тот же .out). По поводу остальных функций - вводим в терминале man gcc.

Работа в C/C++

Пример использования ссылок и оператора new (некое подобие динамического массива, чем плюсы выгоднее отличаются от Си - в них оно удобнее). Код: <source lang = "c">

 #include <stdio.h>
 #include <math.h>
 #include <stdlib.h>
 #define size 10
   int* mas()
 {
   int* m = new int[size];
   int i;
  for (i=0; i<size; i++)
  {
    m[i] = i;
  }
    return m;
 }
   int main(void)
 {
   int i;
   int* m = mas();
 for (i=0; i<size; i++)
   {
   printf("%d\n", m[i]);
   }
 }

</source> Компилировать massiv.cpp с помощью g++ massiv.cpp -o massiv.out

Интерполяционный полином Лагранжа. <source lang = "c">

  1. include <stdio.h>
  2. include <math.h>

double InterpolateLagrangePolynomial (double x, double* x_values, double* y_values, int size) {

       double lagrange_pol = 0;
       double basics_pol = 1;

       for (int i = 0; i < size; i++)
       {
               basics_pol = 1;
               for (int j = 0; j < size; j++)
               {
                       if (j == i) continue;
                       basics_pol *= (x - x_values[j])/(x_values[i] - x_values[j]);             
               }
               lagrange_pol += basics_pol*y_values[i];
       }
       return lagrange_pol;

}


double testF(double x) {

       return  x*x - x + sin(x)*exp(x); // for example

}

int main(void) {

       const int size = 10;
       double x_values[size];
       double y_values[size];


       for (int i = 0; i < size; i++)
       {
               x_values[i] = i; 
               y_values[i] = testF(i);
       }

       printf ("%lf\n", InterpolateLagrangePolynomial(2, x_values, y_values, size));

       return 0;

}

</source>

Интегрирование. <source lang = "c">

  1. include <stdio.h>
  2. include <math.h>
  3. include <time.h>
  4. include <stdlib.h>
  5. include <string.h>
  6. define N 1000000
  7. define Pi 3.14159265

float f(float x) { return exp(-sqrt(2*0.413567*203/Pi)*x)*((sin(x) - x*cos(x))*(sin(x) - x*cos(x)))/(x*x*x*x*x) }

float frand() { return (float)(rand()) / RAND_MAX; } //--------------------------------------------------- float Integral(float a, float b, float (*f)(float) ) //монте карло {

float I; int n; float h;

h=(b-a)/N; I=0;

for(n=0; n<N; n++) { I += f(a + (b-a)*frand()); } I = I/N*(b-a);

return I; } //----------------------------------------------------- float Integral1(float a, float b, float (*f)(float) ) //3/8 { float I, h;

h = (b-a)/3; I = ((b-a)/8)*(f(a) + 3*f(a+h) + 3*f(a+2*h) + f(b)); return I; } //----------------------------------------------------- int main(void) {

float result, result1, a, b;

printf("Введите верхний предел интегрирования\n"); scanf("%f", &b); printf("Введите нижний предел интегрирования\n"); scanf("%f", &a);

result = Integral(a, b, &f); result1 = Integral1(a, b, &f); printf("Интеграл равен %f\n", result); printf("Интеграл равен %f\n", result1); } </source>