Главная » Все файлы » Просмотр файлов из архивов » Документы » Краткий конспект семинарских занятий по языку C - Н.Д. Васюкова_ И.В. Машечкин_ В.В.Тюляева_ Е.М.Шляховая

Краткий конспект семинарских занятий по языку C - Н.Д. Васюкова_ И.В. Машечкин_ В.В.Тюляева_ Е.М.Шляховая, страница 4

2019-05-08СтудИзба

Описание файла

Документ из архива "Краткий конспект семинарских занятий по языку C - Н.Д. Васюкова_ И.В. Машечкин_ В.В.Тюляева_ Е.М.Шляховая", который расположен в категории "". Всё это находится в предмете "операционные системы" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Краткий конспект семинарских занятий по языку C - Н.Д. Васюкова_ И.В. Машечкин_ В.В.Тюляева_ Е.М.Шляховая"

Текст 4 страницы из документа "Краткий конспект семинарских занятий по языку C - Н.Д. Васюкова_ И.В. Машечкин_ В.В.Тюляева_ Е.М.Шляховая"

main()

{

extern int y;

x = y = 10;

printf(“x=%d, y=%d\n”,x,y); /* x=10, y=10 */

}

int y;

В файле вне функций не может встречаться несколько определений переменных (возможно, разных типов) с одним и тем же именем:

int x;

main()

{

...

}

float x;/* ошибка: повторное определение x */

Указание static, примененное к переменной или функции, ограничивает область их видимости концом файла5.

Если используемая переменная определена в другом программном файле, она также должна быть описана со спецификатором extern. При таком описании переменных память не отводится, а только декларируется тип переменной.

Примечание. Переменные, определенные внутри блока, как и формальные параметры функций "перекрывают" переменные с теми же именами, видимые в пределах файла и в пределах программы.

Область существования переменной – это множество всех точек программы, при приходе управления на которые переменная существует, т.е. для нее выделена память. С этой точки зрения можно выделить две группы переменных:

1. Статические переменные

Переменные, являющиеся статическими, существуют на всем протяжении работы программы. Память под эти переменные выделяется на этапе редактирования внешних связей и загрузки программы, тогда же происходит и инициализация статических переменных (следует отметить, что статические переменные по умолчанию инициализируются нулем). Правила определения статических переменных различаются в зависимости от конкретного места программы, в котором это определение встретилось. Для определения статической переменной, локализованной в блоке, используется ключевое слово static, например:

int max; /*статическая переменная вне блока*/

int f(int param)

{

static int min; /* статическая переменная,

определенная внутри блока */

}

Основным свойством статических переменных, определенных внутри блока, является сохранение их значений при выходе из блока. Например:

Все переменные, определенные вне функций, являются статическими.

2. Автоматические переменные

Автоматическими переменными являются все переменные определенные внутри блока (функции) и не являющиеся статическими. Автоматические переменные существуют на протяжении работы блока, в котором они определены, включая блоки, вложенные в данный. Выделение памяти под автоматические переменные и их инициализация осуществляется каждый раз при входе в блок (начальное значение по умолчанию для автоматических переменных не определено).

При выходе из блока память, выделенная под автоматические переменные, освобождается. Таким образом, автоматические переменные являются более эффективным средством при работе с памятью, чем статические переменные. Однако, надо учитывать тот факт, что инициализация автоматических переменных, фактически, эквивалентна присваиванию значений и требует определенных временных затрат на исполнение этого кода. В качестве средств оптимизации Си программ предлагается возможность использования так называемых регистровых переменных. Это достигается за счет использования квалификатора register в определении переменных, что указывает компилятору, что данную переменную в целях ускорения программы имеет смысл разместить на регистрах, однако компилятор может проигнорировать это указание. Квалификатор register может применяться только к автоматическим переменным и формальным параметрам функций. Независимо от того, была ли переменная, описанная с квалификатором register, действительно размещена на регистрах или нет, для нее не определено понятие адреса (т.е. не определена операция &).

Рис.1

Обычно автоматические переменные, как и формальные параметры функций, реализуются с использованием стека. Параметрам функции отводится память в стеке, в которую копируются фактические значения. По окончании работы функции память освобождается. Рассмотрим состояние стека на примере рекурсивной функции (cм. Рис.1). В примере каждый раз при вызове функции f в стеке отводится место для параметра a и автоматической переменной i, а также для автоматической переменной r в случае, если ее не удалось разместить на регистрах. Заметим, что при рекурсивном вызове функции f еще раз выделяется память в стеке под автоматические переменные и параметры нового вызова. При выходе из функции выделенная в стеке память освобождается.

Препроцессор6. Стандартная схема трансляции Си-программы состоит из двух этапов: препроцессирование и собственно компиляция. Препроцессор выполняет макроподстановку, условную компиляцию, подключение файлов и тем самым формирует текст программы, поступающий на вход компилятору.

Программный файл может содержать директивы препроцессору. Директивам препроцессору предшествует знак #. Например:

#include <stdio.h> /* подключение файла */

#define a “max=%d\n” /* макроподстановка */

int x=15;

max(int);

main()

{ int y, u;

scanf(“%d”,&y);

u=max(y);

printf(a,u);

}

max(int f)

{ int k;

k=(x>f)?x:f;

return k;

}

Включение файлов. На место директивы #include препроцессор подставляет содержимое указанного в ней файла. Порядок поиска подключаемого файла зависит от реализации Си. Если имя файла заключено в < >, то в UNIX–системах он ищется в стандартном каталоге подключаемых файлов /usr/include, как например в случае:

#include <stdio.h>

Если же имя указано в “ ”, то препроцессор рассматривает его как относительный путь от местонахождения того файла, в котором встретился #include или, если имя начинается с “/” – как абсолютный путь от корня. Например:

#include “myfile.h”

#include “/usr/stuff/myfile.h”

Включаемые файлы, в свою очередь, могут содержать #include-директивы.

Макроподстановка.

#define имя подставляемый_текст

Начиная от места появления #define и до конца файла, везде, где встречается имя, указанное в #define, вместо него препроцессор подставляет заданный текст (кроме случаев, когда имя встречается внутри текста в кавычках).

Примеры:

#define NUMBER 10

#define DOUBLED_NUMBER NUMBER*2 /*в #define-определении можно использовать более ранние определения7 */

#define PrintHello printf(“Hello,\

world”); /* “\” используется для продолжения определения на следующей строке */

Можно определить макроподстановку с параметрами, что позволяет изменять подставляемый текст в зависимости от фактических параметров. Например:

#define SQR(x) ((x)*(x))

#define Print(x) printf(#x “ = %d\n”, x)

/* имя формального параметра, встретившееся в “”, не заменяется на фактический параметр, но если перед именем формального параметра стоит #, то в макрорасширении #имя_формального_параметра будет заменено на строку “фактический_параметр”, после чего в нашем примере строки конкатенируются */

main()

{

int n = 4;

Print(n); /* выводит на печать: n = 4 */

Print(SQR(n)); /* SQR(n) = 16 */

/* следующие два примера демонстрируют необходимость скобок в определении SQR(x) для обеспечения нужного порядка вычислений */

Print(SQR(n+2)); /* SQR(n+2) = 36 */

Print(256/SQR(n)); /* 256/SQR(n) = 16 */

}

Оператор ## позволяет «склеивать» аргументы в макроподстановке, например: #define bond(left, right) left##right

Таким образом для bond(name, 123)будет сгенерировано name123

Примечание. Повторный #define для того же имени является ошибкой, если подставляемые тексты не совпадают с точностью до разделяющих пробельных символов. Препроцессору можно дать указание «забыть» определенное имя с помощью директивы

#undef имя

(если имя не было ранее определено, ошибки не произойдет)

Условная компиляция. Другой пример использования препроцессора – управление выборочным включением того или иного текста в программу в зависимости от вычисляемого на этапе препроцессирования условия.

if-директива выражение_или_идентификатор

...

[{#elif выражение}

...

#else

... ]

#endif

где if-директива – это:

#if константное_выражение

(вычислить выражение и если получилось ненулевое значение, то включить весь текст до строки else-директивы или #endif)

#ifdef имя /* 1, если имя уже определено */

#ifndef имя /*1, если имя не было определено */

Например, во избежание повторного включения файла "myfile.h" его оформляют следующим образом:

ТЕМА 6. Инициализация одномерных массивов. Массивы указателей и их инициализация. Аргументы командной строки. Указатели на функции.

При инициализации массивов инициализирующие значения заключаются в фигурные скобки и, если их не хватает, то оставшимся элементам присваиваются нулевые значения. Например:

int m1[5]={0,1,2,3}, m2[10]={0};

Последний элемент массива m1 и все элементы массива m2 будут обнулены. Если размер массива не указан, то он определяется по количеству инициализирующих значений.

Массив типа char (строка) может быть проинициализирован двумя способами:

char str1[ ]={ ‘a’,’b’,’c’,’\0’};

char str2[ ]=”abc”;

Под строки str1 и str2 будет отведено по 4 байта. Строка str2 будет автоматически дополнена нулевым байтом.

При инициализации указателя на строку, в него записывается адрес константной строки, элементы которой изменять нельзя.

char *p=”abc”;

*p=’A’; /* Неправильно */

*str2=’A’; /* Правильно */

Язык Си позволяет инициализировать массив указателей, например:

char *mas[]={“for”,”while”,”do”,”return”,NULL};

Элементами массива mas являются адреса строковых констант.

mas[i] – адрес i-ой строки ( адрес её нулевого символа ).

mas[i]+j – адрес j-го символа i-ой строки.

Задача 1. Написать функцию, которой в качестве аргумента передается массив указателей на строки (признак конца - нулевой указатель). Распечатать последний символ каждой строки.

void fp(char *s[])/* void fp(char **s)

тождественно */

{ int i=0;

while(s[i]!=NULL) {

printf(“%c\n”,

*(s[i]+ strlen(s[i])-1));

i++;

}

}

Задача 2. Написать фрагмент программы, размещающий в динамической памяти вводимые из стандартного входного потока вещественные числа. Количество вводимых чисел вводится первым.

... int k,i;

double *p;

. . .

scanf(“%d”,&k);

p=(double*)malloc(k*sizeof(double));

for(i=0;i<k;i++) scanf(“%lf”,p+i);

Задача 3. Ввести строку из стандартного входного потока длиной не более ста символов и разместить ее в динамической памяти.

... char str[100],*p;

...

if(gets(str)!=NULL) {

p=(char*)malloc(strlen(str)+1);

strcpy(p,str);

}

В операционной системе имеется возможность передавать аргументы запускаемой программе при помощи командной строки. Стандарт ANSI C определяет только 2 аргумента функции main():

main(int argc, char *argv[])

В первом (argc) передается количество аргументов командной строки, во втором (argv) – адрес массива указателей на строки-аргументы. По соглашению argv[0] всегда содержит адрес строки, в которой записано имя вызванной программы. Поэтому если argc равен 1, то в командной строке после имени программы никаких аргументов нет. Кроме того, всегда выполняется соглашение argv[argc]=NULL.

Стандарт POSIX.1 определяет третий аргумент функции main():

main(int argc, char *argv[], char *envp[])

Массив envp[] содержит указатели на переменные окружения, передаваемые программе. Каждая переменная – строка вида

имя_переменной = значение_переменной

POSIX.1 также рекомендует доступ к окружению из программы через глобальную переменную environ:

еxtern char **environ;

В языке Си можно определять указатели на функции, которые ничем не отличаются от обычных указателей. Указатель на функцию можно присваивать, размещать в массиве, передавать в функцию в качестве параметра. Например:

double (*fp)(double);

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

double x=1.57,y;

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5259
Авторов
на СтудИзбе
420
Средний доход
с одного платного файла
Обучение Подробнее