БИЛЕТ 24.
1) Описания и определения
ПЕРВЫЙ
Имя (идентификатор) следует описать прежде, чем оно будет использоваться
в программе на С++. Это означает, что нужно указать его тип, чтобы
транслятор знал, к какого вида объектам относится имя. Роль описаний не сводится лишь к привязке
типа к имени. Большинство указанных описаний одновременно являются
определениями, т.е. они создают объект, на который ссылается имя.
char ch;
int count = 1;
char* name = "Njal";
struct complex { float re, im; };
complex cvar;
extern complex sqrt(complex);
extern int error_number;
typedef complex point;
float real(complex* p) { return p->re; };
const double pi = 3.1415926535897932385;
struct user;
template<class T> abs(T a) { return a<0 ? -a : a; }
enum beer { Carlsberg, Tuborg, Thor };
ВТОРОЙ
Важное отличие языка СИ от других языков является отсутствие принципа умолчания, что приводит к необходимости объявления всех переменных используемых в программе явно вместе с указанием соответствующих им типов.
Объявление говорит компилятору, что такое имя или программный элемент существует. Определение описывает данное имя. Любое имя для использования должно быть объявлено. Вводят одно или больше имен в программу.
Пример объявлений и определений:
int i;
int j = 10;
При объявлении простой переменной, структуры, смеси или объединения, а также перечисления, описатель - это простой идентификатор. Для объявления указателя, массива или функции идентификатор модифицируется соответствующим образом: звездочкой слева, квадратными или круглыми скобками справа.
2) Арифметические операции
Унарные операторы
Выражения, содержащие унарные операторы, группируются справа налево.
1) Унарный минус "-"
Результат - величина, равная операнду по модулю, но имеющая обратный знак. Операнд должен иметь арифметический (числовой) тип.
Например,
printf("Унарный минус:\n");
char var1='a';
int var2=12;
float var3=-2.45;
printf("-\'a\'=%c; -12=%i; -(-2.45)=%.2f\n", -var1, -var2, -var3)
Унарный минус можно применить и к беззнаковому числу. Результат в этом случае будет равен разности между значением операнда и 2^n, где n - количество бит в беззнаковом целом (что дает тот же ожидаемый результат).
printf("Унарный минус применительно к беззнаковому:\n");
unsigned char var4='a';
unsigned int var5=12;
printf("-\'a\'=%c; -(12)=%i\n", -var4, -var5);
2) Оператор "~"
Результат - дополнение операнда до единицы. Операнд должен иметь целочисленный тип.
Например,
printf("Оператор ~ (дополнение до единицы)\n");
int var6=10;
int var7=-13;
printf("~10=%i; ~(-13)=%i\n", ~var1, ~var2);
В результате выполнения этой программки на экран выведется:~10=-11; ~(-13)=12
3) Оператор инкрементации "++"
Его действие аналогично увеличению переменной-операнда на единицу:
a++ == a=a+1;
Оператор инкрементации можно использовать в префиксной (++а) и постфиксной (а++) форме. Отличие между ними заключается в том, что в префиксном случае операнд вначале увеличивается, а затем используется. В постфиксной форме в выражении используется старое значение операнда, и только затем он увеличивается.
Понятно, что если инкрементация используется сама по себе, то разницы между формами нет:
a = 1;
a++; // теперь a=2
++a; // теперь a=3
Однако если инкрементация используется внутри выражения, то выбор формы становится важным:
a=1;
b=a++; // теперь b=1; a=2;
c=++a; // теперь c=3; a=3;
Как всегда, если есть малейшая вероятность запутаться в конструкции, надежнее такую конструкцию не строить. Помните о законе Мэрфи.
4) Оператор декрементации "--"
Аналог оператора ++, который уменьшает значение операнда на единицу.
a-- == a=a-1;
Его также можно использовать в префиксной и постфиксной форме:
a=10;
b=a--; // теперь b=10; a=9;
c=--a; // теперь c=8; a=8;
Бинарные операторы
1) Операторы сложения и вычитания "+" и "-"
Результат операции - соответственно сумма или разность операндов. При этом операнды могут иметь не только числовой тип, но и тип указатель.
Операция сложения, как известно, ассоциативна, так что a+b == b+a
При этом компилятор может сам перегруппировывать подвыражения с одинаковым приоритетом.
Пример. Программа должна посчитать периметр произвольного четырехугольника, который задан длинами сторон.
#include <stdio.h>
void main(void) {
printf("Программа вычисляет периметр произвольного четырехугольника,\n");
printf("заданного длинами сторон.\n");
float a, b, c, d;
printf("Введите длины сторон через пробел или [Enter]\n");
scanf("%f %f %f %f", &a, &b, &c, &d);
float sum=a+b+c+d;
printf("Периметр этого четырехугольника равен %.2f\n", sum);
}
2) Операторы умножения и деления "*", "/" и "%"
Результат операции "*" - произведение операндов. Операция ассоциативна, порядок вычисления операндов (если они представлены выражениями) компилятор определяет сам.
#include <stdio.h>
void main(void) {
printf("Программа вычисляет периметр и площадь поверхности\n");
printf("параллелепипеда, заданного длинами своих ребер.\n");
float a, b, c;
printf("Введите длины ребер через пробел или [Enter]\n");
scanf("%f %f %f", &a, &b, &c);
double p = 4*(a+b+c);
double s = 2*(a*b+b*c+a*c);
printf("Периметр этого параллелепипеда равен %.2f\n", p);
printf("А площадь его поверхности равна %.2f\n", s);
}
Результат операции "/" - частное от деления первого операнда на второй.
При делении целых положительных операндов результат усекается в направлении нуля, так что
8/5=2
10/4=2
При этом, если один из операндов отрицателен, то способ округления машиннозависим.
#include <stdio.h>
void main(void) {
printf("Задача.\nИзвестно, что x% от целого составляет a.\n");
printf("Найти значение целого.\n");
float x, a;
printf("Введите x: "); scanf("%f", &x);
printf("Введите a: "); scanf("%f", &a);
double z=a/x*100;
printf("То самое целое, от которого брали проценты, равно %.2f\n", z);
}
Результат операции "%" - остаток от деления первого операнда на второй. Операнды обязаны принадлежать к целочисленному типу.
Практически во всех системах остаток имеет тот же знак, что и делимое.
-10%6=-4
10%(-3)=1
#include <stdio.h>
void main(void) {
printf("10/4=%i; остаток %i\n", 10/4, 10%4);
printf("-10/6=%i; остаток %i\n", -10/6, -10%6);
printf("10/(-3)=%i; остаток %i\n", 10/(-3), 10%(-3));
}
После выполнения эта программка выдаст:10/4=2; остаток 2
-10/6=-1; остаток -4
10/(-3)=-3; остаток 1
*************************************24 - 3
Напишите программу, которая вычисляет частичную сумму ряда 1-1/3+1/5-1/7+1/9-… и сравнивает полученное значение с ?/4 (При суммировании достаточно большого количества членов этого ряда величина частичной суммы приближается к ?/4). Как только абсолютная величина разности их станет меньше введенного с клавиатуры числа е, выдать значение частичной суммы и количество слагаемых в ней.
#include<conio.h>
#include<stdio.h>
#include<math.h>
float x=0;
float e = 0.01;
float minus=-1;
int znam;
float p;
void main()
{
clrscr();
int i = 0;
do {
minus *= (-1);
znam = 2*i+1;
x += (minus/znam);
p=fabs(M_PI_4 - x);
i++;
} while( p > e);
printf("Pi = %f\nx = %f\neps = %f",M_PI_4,x,p);
getch();
}
*************************************24 - 4
Напишите функцию, которая проверяет, есть ли в полученной ею в качестве параметра строке точка и пробел перед каждой заглавной буквой, кроме первой (алфавит латинский). Если нет, то функция вставляет их.
#include<conio.h>
#include<stdio.h>
int n = 10;
char s[]="YouFuCk!!!";
int i,j;
void main()
{
clrscr();
for (i=1;i<n;i++)
if(s[i] >= 65 && s[i] <= 89)
{
if (s[i-1] != ' ')
{
for (j=n;j>=i;j--)
s[j] = s[j-1];
s[i]=' ';
n++;
s[n]='\0';
}
if (s[i-1] != '.')
{
for (j=n;j>=i;j--)
s[j] = s[j-1];
s[i]='.';
n++;
s[n]='\0';
i+=2;
}
}
getch();
}