Содержание
Список контрольных вопросов
№ | Вопрос | № | Вопрос |
1. | Что такое область действия переменных? | 16. | Передача параметров по значению. |
2. | Что такое область видимости переменных? | 17. | Передача параметров по адресу. |
3. | Объясните понятие: оператор расширения области видимости. | 18. | Передача параметров по ссылке. |
4. | Что такое классы памяти? | 19. | Параметр со значением по умолчанию. |
5. | Какие бывают виды операций? | 20. | Передача массивов в качестве параметров. |
6. | Объясните понятие $L$-значения. | 21. | Описание функции main(). |
7. | Что такое указатель. | 22. | Описание функции с переменным числом параметров. |
8. | Операция взятия адреса. | 23. | Методика перезагрузки функций. |
9. | Операция разадресации. | 24. | Ввод/вывод информации. |
10. | Методика сложения и вычитания указателя с константой. | 25. | Переименование типов. |
11. | Методика разности двух указателей. | 26. | Что такое перечисление? |
12. | Что такое ссылка? | 27. | Что такое структуры? |
13. | Что такое одномерный массив? | 28. | Что такое объединения? |
14. | Что такое многомерный массив? | 29. | Работа с динамической памятью. |
15. | Объясните понятие С-строка. | 30. | Директивы препроцессора. |
Стоимость ответов на контрольные вопросы
💡 Мы предлагаем студентам $3$ варианта помощи по контрольным вопросам:
- Сокращенные ответы, по интересующим студента вопросам. Стоимость сокращенного ответа на один контрольный вопрос составляет $50$ рублей (пример см. чуть ниже).
- Развернутые ответы, по интересующим студентам вопросам. Стоимость развернутого ответа на один контрольный вопрос составляет $150$ рублей (пример см. чуть ниже).
- Помощь репетитора по программированию Александра Георгиевича (звонить по номеру телефона $8\ (926)\ 610-61-95$). Минимальная длительность одного занятия составляет $90$ минут и стоит ровно $1\ 000$ рублей.
Пример сокращенного ответа на вопрос: «Что такое классы памяти?»
В языке СИ все переменные помимо типа обладают еще и классом памяти. Всего существует четыре класса памяти переменных: автоматический (auto), статический (static), регистровый (register) и внешний (extern).
- Автоматический класс памяти по умолчанию имеют все локальные переменные. Область видимости таких переменных ограничена блоком.
- Переменная, имеющая статический класс памяти, существует в течение всего жизненного цикла программы. Возведение локальных переменных в ранг статических позволяет поддерживать их значения между вызовами функций.
- Когда происходит объявление регистровой переменной, то это означает, что мы «просим» компилятор о том, чтобы переменная располагалась в регистре, а не в оперативной памяти.
- Внешние переменные в языке СИ используется тогда, когда нужно иметь доступ к переменной существующей в другом модуле или, когда переменная объявляется в программе ниже, чем ссылка на нее.
💡 Такой сокращенный ответ можно у нас заказать за $50$ рублей.
Пример развернутого ответа на вопрос: «Что такое классы памяти?»
Стандарт языка СИ поддерживает четыре спецификатора класса памяти:
автоматический (auto) | статический (static) | регистровый (register) | внешний (extern) |
Эти спецификаторы сообщают компилятору, как он должен стараться разместить эти переменные в памяти. Общая форма объявления переменных в этом случае принимает вид:
<спецификатор класса памяти> <тип данных> <имя переменной>;
Класс памяти «auto»
По умолчанию локальные переменные имеют спецификатор auto. Такие переменные располагаются в стеке, а их область видимости ограничена блоком их объявления. Глобальные переменные не могут быть объявлены как auto, потому что располагаются в data-сегменте.
В данном примере продемонстрирован принцип работы локальной автоматической переменной:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <conio.h> //------------------------------------------------------------------------------------- // главная функция программы (точка входа) //------------------------------------------------------------------------------------- int main(void) { int x = 10; int auto y = 20; // локальная автоматическая переменная (аналог int y = 20;) printf("x + y = %d + %d = %d", x, y, x + y); getch(); // задержка работы программы, чтобы можно было просмотреть результаты return 0; // завершение работы программы и передача управления в ОС } //------------------------------------------------------------------------------------- |
Класс памяти «static»
Переменные объявленные со спецификатором static, хранятся постоянно внутри своей функции или файла. В отличие от глобальных переменных они невидимы за пределами своей функции или файла, но они сохраняют свое значение между вызовами. Локальные и глобальные переменные, имеющие спецификатор static, ведут в программе себя по-разному.
В данном примере продемонстрирован принцип работы локальной статической переменной:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> #include <conio.h> void F(void) { static int number = 1; number += 2; printf("%d\n", number); } int main(void) { F(); F(); F(); getch(); return 0; } |
Результаты работы программы
Очень важно понимать, что в отличие от простой локальной переменной, статическая локальная переменная продолжает существовать между вызовами функций. Простая локальная переменная создается заново при каждом вызове, а затем уничтожается.
Глобальная переменная со спецификатором static заставляет компилятор создать глобальную переменную, видимую только в том файле, в котором она объявлена. При разработке больших и сложных программ для «сокрытия» переменных можно смело применять спецификатор static.
Класс памяти «register»
Спецификатор register можно применять к переменным любого типа данных. Стандарты языка C89 и C99 обязывают компилятор обращаться с переменными, имеющими спецификатор register, так быстро, насколько это возможно. При этом символьные и целочисленные переменные размещаются в регистрах процессора.
Разные компиляторы могут по-разному обрабатывать переменные со спецификатором register. Иногда спецификатор register попросту игнорируется компилятором и переменная обрабатывается как обычная.
Спецификатор register можно применять только к локальным переменным и формальным параметрам функций. Регистровые переменные идеально подходят для оптимизации скорости работы цикла. Некоторые профессиональные программисты вообще настаивают на том, чтобы спецификатор register был применен только к переменным-счетчикам циклов.
В данном примере продемонстрирован принцип работы локальной регистровой переменной:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <stdio.h> #include <conio.h> #include <math.h> #include <locale.h> #define MILLION 1000000 // миллион //------------------------------------------------------------------------------------- // проверки числа на совершенность // совершенное число - натуральное число, равное сумме всех своих собственных делителей // 0 - входное натуральное число не является совершенным // 1 - входное натуральное число является совершенным //------------------------------------------------------------------------------------- int IsPerfect(const long long pnumber) { int result = 0; long long sumDividers = 0; // сумма всех собственных делителей register long long divider; // текущий делитель for(divider = 1; divider <= pnumber/2; divider++) if(pnumber % divider == 0) // если текущее значение счетчика является делителем sumDividers += divider; // если сумма всех делителей совпала с самим числом, значит оно совершенное if(pnumber == sumDividers) result = 1; return result; } //------------------------------------------------------------------------------------- // главная функция программы (точка входа) //------------------------------------------------------------------------------------- int main(void) { register long long number; // счетчик цикла от 2 до миллиона setlocale(LC_ALL, "rus"); printf("Список совершенных чисел из отрезка [1 ... 1 000 000]:\n"); for(number = 2; number <= MILLION; number++) if(IsPerfect(number) == 1) printf("\t%lld\n", number); getch(); // задержка работы программы, чтобы можно было просмотреть результаты return 0; // завершение работы программы и передача управления в ОС } //------------------------------------------------------------------------------------- |
Результаты работы программы
Практический ощутимый эффект от применения спецификатора register может быть получен только для переменных целого и символьного тип.
Класс памяти «extern»
Спецификатор extern указывает на то, что к переменной применяется внешнее связывание, именно поэтому значения таких переменных будут доступны во всей программе. Если нужно сослаться на переменную, определенную в другой части программы, необходимо объявить ее как внешнюю (extern).
В данном примере продемонстрирован принцип работы внешних переменных:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> #include <conio.h> //------------------------------------------------------------------------------------- // главная функция программы (точка входа) //------------------------------------------------------------------------------------- int main(void) { extern int x, y; printf("x + y = %d + %d = %d", x, y, x + y); getch(); // задержка работы программы, чтобы можно было просмотреть результаты return 0; // завершение работы программы и передача управления в ОС } //------------------------------------------------------------------------------------- // блок внешних деклараций int x = 10; int y = 20; |
Спецификатор extern играет большую роль в программах, состоящих из многих файлов. На практике профессиональные программисты обычно включают объявления extern в заголовочные файлы, которые просто подключаются к каждому файлу исходного текста программы.
P.S. Спецификатор extern можно применять в объявлении функций, но в этом нет никакой необходимости.
💡 Такой развернутый ответ можно у нас заказать за $150$ рублей.
Для оформления заказа пишите на почту: proglabs@mail.ru.
Время нашего ответа обычно составляет не более 10 минут.
Добавить комментарий