340 likes | 511 Views
Инструкции C++. Формат: if ( условие ) оператор ; else оператор ; Пример: if (i !=0 ) { if (j) j++; if(k) k++; else if(p) k--; } else i--;. Формат: switch ( выражение ) { case константа : набор операторов ; break ; … default : набор операторов ; }. Инструкция выбора.
E N D
Формат: if(условие)оператор; elseоператор; Пример: if (i!=0) {if (j) j++;if(k) k++;else if(p) k--; } else i--; Формат: switch (выражение){caseконстанта:набор операторов;break;…default:набор операторов; } Инструкция выбора Условная инструкция
Циклы • С предусловием: while (условие) оператор; • С постусловием: do оператор;while (условие); • Пересчетного типа: for(инициализация;условие;приращение)оператор;
break; Пример: for(int I=0; I<10; I++) {cout << I << ‘\n’;if( I==5) break; } continue; Пример: for(;;) { cin >>I;if(I>0) continue;goto loop_exit; } loop_exit: … Инструкции перехода break; } Инструкция безусловного перехода Формат:goto метка; Используется только в случаях крайней необходимости!
Функции • Функция до её использования должна быть описана или объявлена в виде (имена параметров игнорируются): Прототип_функции; • Функция должна быть описана только один раз в виде: Прототип_функции{тело_функции } • Формат прототипа: Тип_возвращаемого_значения имя(список_параметров) • Формат списка параметров: тип имя_аргумента,…,тип имя_аргумента • Функцию можно определить со спецификатором inline inline int fac(int n) {return (n<2)?1:n*fac(n-1);} • Программа начинает выполняться с функции main.
Возвращаемое значение • Любая функция, если она не объявлена как void, должна возвращать значение. • Это значение задается в инструкцииreturn выражение;-инициализации неименованной переменной возвращаемого типа. • Функция может иметь несколько инструкций return. • Если функция не возвращает значения, то выражение в инструкции return может быть пустым или вызовом функции типа void.
Пример. int fac(int n) {if(n>1) return n*fac(n-1);return 1;} Ошибка. int* fp(void) {int& fr(void) { int local=1;return &local; return local;} } Возвращается адрес локальной переменной, которая будет уничтожена. Значение, на которое будет указывать этот адрес, будет меняться непредсказуемо!
По значению void val(int i) { i++; } void main() { int k=0; val(k); cout << “k=” << k; } По ссылке void ref(int& j) { j++; } void main() { int k=0; ref(k); cout << “k=” << k; } Передача аргументов сout << “k=“ << k;сhar c=‘0’; ref(c); cout << “ c=” << c;}Результат: k=1 c=0 - ?! Результат: k=0 Результат: k=1 Выход:void val(const тип&); - указывает на то, что ссылка используется только из соображений эффективности.сonst тип* - говорит, что значение объекта, на который ссылается указатель, не может изменяться в функции. • Функции, которые модифицируют аргументы переданные по ссылке, делают программу трудно читаемой и в большинстве случаев их следует избегать. • В тоже время, большие объекты эффективнее передавать по ссылке, чем по значению.
Функции с неопределенным числом аргументов Файл stdio.h printf(char*,…) #include <iostream.h>#include <stdarg.h>int average( int first, ... );void main(){cout << average( 2, 3, 4, -1 ) <<‘ ’; cout << average( 5, 7, 9, 11, -1 ) << ‘ ’; cout << average( -1 ) << ‘\n’; }int average( int first, ... ) { int cnt = 0, sum = 0, i = first;va_list mkr; va_start( mkr, first );while( i != -1 ) { sum += i; cnt++;i = va_arg(mkr,int); }va_end( mkr ); return( sum ? (sum / cnt) : 0 );} void* mkr; mkr=&first +sizeof first; *((int*)mkr)++; mkr=0; Результат: 3 8 0
Аргументы функции main #include <iostream.h> void main(int n,char* s[]) { cout << s[0];int i=1; while( i<n ) cout << ' ' << s[i++]; cout << '\n'; } Результат: tst.exe a bb ccc Аргументы по умолчанию void print(int n,int sys=10){ if(sys==16) cout<< hex; else if(sys==8) cout<< oct; else cout << dec; cout << n << '\t'; } void main() {print(31,8); print(31); print(31,16); } 37 31 1f
Ввод/вывод Ввод-вывод на консоль. Файловый ввод-вывод.
Ввод/вывод символов • int getchar(); • int putchar(int); #include <stdio.h> void main() { int c; while(c=getchar()) putchar(c); } #include <stdio.h> void main() { int c; while((c=getchar())!=EOF) putchar(c); } int getch(); int getche();
Ввод-вывод строк • char *gets(char*) • int puts(char*) #include <stdio.h> void main() { char s[80]; gets(s); puts(s); } NB:gets(); - не проверяет выход за границы массива!
Форматированный ввод/вывод • Спецификаторы преобразования: • %c – символ; • %s – строка; • %d или %i – десятичное целое со знаком; • %u – десятичное целое без знака; • %о – восьмеричное без знака; • %х или %Х – шестнадцатеричное без знака; • %е или %Е – вещественное в форме с плавающей точкой; • %f – вещественное в форме с фиксированной точкой; • %g или %G = %f или %e, зависит от того, какая форма короче; • %p – указатель; • %% – знак %. • int printf(const char*,…) • int scanf(const char*,…)
Форматированный ввод/вывод <Модификатор формата> ::= h | l | L | F | N | < Модификатор точности><Модификатор формата>| <Модификатор минимальной ширины поля> <Модификатор формата>| #<Модификатор формата>|-<Модификатор формата>| +<Модификатор формата>| ˽<Модификатор формата> < Модификатор точности>::= .* | .<Целое число> <Модификатор минимальной ширины поля>::= * | <Натуральное число> | 0<Натуральное число> • int printf(const char*,…) • int scanf(const char*,…)
Пример #include <stdio.h>void main() {int i1,i2; double a=0.1e-6; char s[80];scanf(“%d %d %s“,&i1,&i2,s),printf(“i1=%i i2=%i %5.7s %s\n“,i1,i2,s,s);printf("%10g %10g\n",a,1000*a);printf("%#0*.*g\n",i1,i2,a);printf("%-20g%c\n",a,'*');} i1=21 i2=10 1234567 1234567890 1e-07 0.0001 0000001.000000000e-07 1e-07 *
Файловый ввод/вывод FILE *имя; • fopen(); • fputc(); или putc(); • fputs(); • fprintf(); • rewind(); • fseek(); • remove(); • fclose(); • fgetc(); или getc(); • fgets(); • fscanf(); • feof(); • ftell(); • ferror();
Открытие файла rbОткрыть текстовый/двоичный файл для чтения; wbСоздать текстовый/двоичный файл для записи; abДобавить в конец текстового/двоичного файла; r+b Открыть текстовый/двоичный файл для чтения/записи; w+bСоздать текстовый/двоичный файл для чтения/записи a+bДобавить в конец текстового/двоичного файлаили создать текстовый/двоичный файл для чтения/записи fopen(const char* Имя, const char* Режим); Прямой доступ fseek(FILE *Уф, longчисло_байт, intТочка_отсчета); Точка отсчета: SEEK_SET От начала файла SEEK_CUR От текущей позиции SEEK_END От конца файла
Пример 123 12a456789 #include <stdio.h> #include <stdlib.h> void main() { FILE *fp; char ch; if(!(fp=fopen("file.dat","r+"))) { printf("File open error!\n"); exit(1); } for(int i=0;i<3;i++) { ch=fgetc(fp); putchar(ch); } long k=ftell(fp); fseek(fp,k-1,SEEK_SET); fputc('a',fp); rewind(fp); while(!feof(fp)) { ch=fgetc(fp); putchar(ch); } fclose(fp); }
Полиморфизм –один интерфейс, множество методов void print(long); // печать целого void print(char*);// печать символьной строки void print(float); // печать вещественного Проблема: print(10); • Не требуется преобразования типа (int и const int). • Существует стандартное преобразование типа с расширением точности (int в long). • Тоже с возможной потерей точности (double в int). • Преобразование типа определено пользователем. • С переменным числом аргументов.
Указатель на функцию #include <iostream.h> #include <math.h> double I(double a,double b,int n,const double (&F)(double)){ double h=(b-a)/n--,s=(F(a)+F(b))/2; while(n--) s+=F(a+=h);return s*h;} double f(double x) { return x; } void main(){ cout << "I( x )= " << I(0.,1.,100,f) << endl;cout << "I( Sin(x) )= " << I(0.,3.14159,100,sin) << endl;} Результат: I( x )= 0.5I( Sin(x) )= 1.999836
Расширение исходного кода #include <имя_файла> #include ”имя_файла” Макросы • Вставить определение #define имя_макроса список_лексем #define va_list void* #define sqr(x) (x)*(x) NB! #define sqr(x) x*x A=sqr(a+b); // A=a+b*a+b; • Определить константу #define имя константа #define array_size 128 #if #ifdef #ifndef … #else #elif … #endif • Условной компиляции
#include <stdio.h> #define eof (-1) int getchar(void); int putchar(int); int printf(char*,…); int scanf(char*,…); #include <math.h> double sin(double); double cosh(double); double exp(double); double sqrt(double); double pow(double,double); #include <string.h> #define NULL 0 char* strcpy(char*, const char*); int strcmp(const char*,const char*); int strlen(const char*); char* strstr(const char*,const char*); #include <conio.h> int getch(void); int getche(void); int putch(int); void gotoxy(int,int); Библиотечные функции
От проектирования процедур к организации данных #include <iostream.h>struct complex { double re,im; }; void main(void){ complex a; a.re=1.; a.im=2.; cout << “a=“; cout << ‘(‘ << a.re << ‘,’ << a.im << ‘)’;} void assign(complex& num, double r, double i) { num.re=r; num.im=i; } void print(complex num) { cout << ‘(‘ << num.re << ‘,’ << num.im << ‘)’; } void main(void) { complex a; assign(a,1.,2.); cout << ‘a=“; print(a); }
Инкапсуляция #include <iostream.h> struct complex {double re,im;void assign(double r,double i) { re=r; im=i; }void print(void);}; void complex::print(void) { cout << ‘(‘ << re << ‘,’ << im << ‘)’; } void main(void){ complex a; a.assign(1.,2.); cout << “a=“; a.print();}
Сокрытие данных class complex { double re,im; public: void assign(double r,double i) { re=r; im=i; } void print(void); }; void complex::print(void) { cout << ‘(‘ << re << ‘,’ << im << ‘)’; } void main(void){ complex a,b; a.assign(1.,2.); b=a; cout << “b=“; b.print(); } #include <iostream.h> struct complex { private:double re,im; public:void assign(doble r,double i) { re=r; im=i; }void print(void); }; void complex::print(void) { cout << ‘(‘ << re << ‘,’ << im << ‘)’; } void main(void){ complex a,b; a.assign(1.,2.); b=a; cout << “b=“; b.print(); }
Конструкторы class complex { double re,im; public:complex(double r=0.,double i=0.) { re=r; im=i; }void print(void) const; }; void complex::print(void) const {cout << ‘(‘ << re << ‘,’ << im << ‘)’; } void main(void){ const complex a,b(1.2,2.3),c=5.; cout << “a=“; a.print(); cout << ‘\t’; cout << “b=”; b.print(); cout << ‘\t’; cout << “c=”; c.print(); cout << endl; } Результат: a=(0,0)b=(1.2,2.3) c=(5,0)
Преобразование типов class complex { double re,im; public:complex(double r=0.,double i=0.) { re=r; im=i; }operator double() { return sqrt(re*re+im*im); }void print(void) const; }; void complex::print(void) const {cout << ‘(‘ << re << ‘,’ << im << ‘)’; } void main(void){ complex a(3.,4.);cout << “|a|=” << (double)a << endl;} Результат: |a|=5
Перегрузка операторов class complex { double re,im; public:complex(double r=0.,double i=0.) { re=r; im=i; }operator double() { return sqrt(re*re+im*im); }complex operator +(double b){ return complex(re+b,im); }complex operator+(complex a) { return complex(a.re+re,a.im+im); }void print() const { cout << ‘(‘ << re << ‘,’ << im << ‘)’; } }; void main(void) {complex a(3.,4.),b=a+5,c=a+b; cout << “c=”; c.print(); cout << endl; } Результат: c=(11,8) void main(void) {complex a(3.,4.),b=5+a,c=a+b; cout << “c=”; c.print(); cout << endl; } Результат: c=(13,4)
Дружественные функции Результат: (8,4)(8,4) class complex { double re,im; public:complex(double r=0.,double i=0.) { re=r; im=i; }operator double() { return sqrt(re*re+im*im); }friend complex operator+(double,complex);complex operator +(double b){ return complex(re+b,im); }complex operator+(complex a) { return complex(a.re+re,a.im+im); }void print() const { cout << ‘(‘ << re << ‘,’ << im << ‘)’; } }; complex operator+(double a, complex b) { return complex(a+b.re,b.im); } main() { complex a(3.,4.), b=a+5, c=5+a; b.print(); c.print(); }
Перегрузка оператора << class complex { double re,im; public:complex(double r=0.,double i=0.) { re=r; im=i; }operator double() { return sqrt(re*re+im*im); }complex operator +(double b){ return complex(re+b,im); }complex operator+(complex a) { return complex(re+a.re,im+a.im); }friend ostream& operator<<(ostream&,complex&); }; ostream& operator<<(ostream& s,complex& a) { s << ‘(‘ << a.re << ‘,’ <<a.im << ‘)’; return s; } void main(void) { complex a(3.,4.),b=a+5,c=a+b;cout << “c=” << c << endl; } Результат: c=(11,8)
Шаблон template <class T> class complex { T re,im; public: complex(T r=0, T i=0) { re=r; im=i; } operator T() { return sqrt(re*re+im*im); } complex operator+(T b){returncomplex<T>(re+b,im); } complex operator+(complex a) {return complex<T>(re+a.re,im+a.im); } friend ostream& operator<<(ostream&,complex<T>&); }; template <class T> ostream&operator<<(ostream& s,complex<T>& a) { s << '(' << a.re << ',' << a.im << ')'; return s; } void main(void) { complex<double> a(3,4); b=a+5; c=a+b; cout << "с=" << a << endl; } Пример шаблона