Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Язык Си

..pdf
Скачиваний:
6
Добавлен:
20.11.2023
Размер:
7.64 Mб
Скачать

Если вызов макроса имеет вид S = CIRC(a + b);, то после расширения макроса текст будет иметь вид

S = (3.14159*(а+b)*(а+b));

Если вместо #define CIRC(x) (3.141 59*(JC)*(JC)) записать

#define CIRC(x) (3.14159*x*x)

то в первом случае значение выражения не изменится, а во втором случае получится

S = (3.14159*a+b*a+b);

Таким образом, при объявлении макроса рекомендуется за­ ключать в скобки параметры в замещающем тексте и сам заме­ щающий текст.

Пример. Найти минимальное из двух чисел.

#include<stdio.h>

#include<conio.h>

#define MIN(a,b) (a<b ? a:b)

main()

{float a=4,b=3.9;

printf(MMIN=%fM,MIN(a,b));

getch() ;

return 0;

}

8.2. Константы

Константа - это значение, которое не может быть изменено. Константы могут использоваться непосредственно в тексте

программы в любых операторах и выражениях.

8.2.1. Неименованные константы

Неименованная константа не имеет имени.

Вязыке Си имеется четыре типа таких констант.

1.Целые числа.

int a=5,b=a/2;

//5 и 2 целые неименованные

//константы

2. Вещественные числа.

а=3*0.5 //0.5 вещественная неименованная

//константа

3. Символьные константы.

char a=,l ,/b= ,s l; //1 и s - символьные

//неименованные константы

Символьные константы должны заключаться в одинарные ка­ вычки.

4. Строковые константы.

printf("Введите число:");

Здесь "Введите число:" - это строковая неименованная кон­ станта. Строковые константы должны заключаться в двойные ка­ вычки.

8.2.2. Именованные константы

Именованные константы объявляются так же, как перемен­ ные, но с добавлением модификатора const:

const float Pi = 3.14159;

Именованная константа должна быть инициализиро­

вана при объявлении.

const float Pi;

//ОШИБКА!

Часто именованные константы применяются с целью облег­ чить изменение какого-то параметра во всей программе при ее мо­ дификации. Например, вы уже заметили, что массивы часто обра­ батываются в циклеfor кодом, подобным данному:

for(i=0; i<10; i++)

где 10 (или другое целое число) - размер массива. Пусть в про­ грамме имеется 50 таких строк. Представьте, что нужно переде­ лать программу под массив с размером уже не на 10, а на 20 эле­ ментов. Программист будет вынужден исправлять все 50 строк, содержащих данный код. В этом случае удобнее ввести константу, отвечающую за размер массива, например п. Теперь при модифи­ кации программы достаточно исправить только одну строку

const int n=20;

Пример. Найти сумму элементов двумерного массива.

#include<conio.h>

#include<stdio.h> const int n=4,m=3; main()

{int i,j,S=0;

int a [3] [4]={{13,10,-5},{11,2,3},{-6,9,0}, {2,13,-10}};

for(i=0; i<n; i++) for(j=0; j<m; j++)

S+=a[i][j];

printf(MS=%dM,S); getch();

return 0;

}

По умолчанию константа имеет тип int, в остальных случаях следует указывать тип константы. Запись const п = 4, т = 3; ком­ пилятор воспримет как const int п = 4, т = 3;.

В языке Си++ именованные константы можно использовать для задания размеров массива.

int а[п][ш]={{13,10,-5},{11,2,3}, {-6,9,0},{2,13,-10}};

Также в Си-н- в качестве значения константы можно указы­ вать константное выражение, объявленное ранее:

const float Pi = 3.14159;

const float Pi2 = 2*Pi; //Pi - ранее объявленная

//константа

const float К = Pi/180; //Pi - ранее объявленная

//константа

Попытка изменить значение именованной константы приве­ дет к ошибке компиляции.

8.3. Строки

Строка - это одномерный массив символов, заканчивающий­ ся нулевым символом '\0', который используется для того, чтобы отмечать конец строки. Нуль-символ - это не цифра 0, а символ, код которого равен нулю. Он не выводится на печать и в таблице кода ASCII имеет номер 0.

8.3.1.Объявление строк

Вязыке Си нет специального встроенного типа, который можно было бы использовать для описания строк. Вместо этого строки представляются в виде массива элементов типа char^ на­ пример

char str[7];

Начальные значения можно указать при объявлении массива, например

str [7] =,,массивп; //или char str [7] = ("массив"};

Этот вид инициализации является краткой формой стандарт­ ной инициализации массива:

char str[7]={'м1,'а', 'с', 'с','и', 'в1,'\0f};

Обратите внимание на замыкающий нуль-символ. Без него это будет массив символов, а не строка, поэтому если строка в

программе формируется из символов, то она должна заканчиваться символом '\0’. В первом случае компилятор сам подставляет сим­ вол конца строки.

При объявлении символьных строк следует иметь в виду, что каждая строка должна оканчиваться символом '\0', и поэтому раз­ мер строки должен быть по крайней мере на единицу больше, чем число символов в строке.

Размер строки может превышать количество хранимых в ней символов.

char str[15]="Borland C++";

Также допускается объявление и инициализация массива без явного указания размера массива. В этом случае компилятор сам определит необходимое количество элементов массива, включая нулевой символ.

char str[]="Borland C++";

Использовать операцию присваивания при инициализации строк можно только при объявлении массива:

char str[20]="массив"; //ПРАВИЛЬНО str="MaccHB"; //ОШИБКА

Пример. Печать символьного массива.

#include<stdio.h>

#include<conio.h>

main()

{int

i;

char

str[6]={'м' ,' a 1,' с' ,1с' ,'и' ,' в 1};

for(i=0;i<6;i++)

printf("%c"/str[i]);

getch(); return 0;

}

Для вывода строк можно использовать функции puts или printf Функция printf менее удобна, чем puts, но более гибка. Раз­

ница заключается в том, что функция printf не выводит автомати­ чески каждую строку текста с новой строки. Вы должны сами ука­ зать, что хотите выводить с новых строк.

Пример. Печать строки.

#include<stdio.h>

#include<conio.h>

main ()

{

char str[]="Borland C++";

printf("%s\n",str);

getch();

return 0;

}

Строки могут объединяться в массивы.

Пример. Печать строкового массива.

#include<stdio.h>

#include<conio.h>

main() {int i,j;

char name[3][10]={"Ivanov", "Petrov", "Sidorov"};

for(i=0;i<3;i++)

printf("%s\n",name[i]);

getch(); return 0;

}

8.3.2. Функции работы со строками

Ввод символьных строк с клавиатуры осуществляется с по­ мощью функций scan/ и gets, вывод - с помощью функций printf и puts. Для использования данных функций необходимо подключить файл stdio.h.

Пример. Ввод-вывод строки.

#include<stdio.h>

#include<conio.h> main()

{char str[20];

printf("Введите строку: "); gets(str);

printf("Вы ввели строку: "); puts(str);

getch(); return 0;

}

Кроме того, для работы со строками существует специальная библиотека, которая находится в файле string.h (табл. 8.1).

Т а б л и ц а 8.1

Основные функции обработки строк

Функция

п/п

1 strlen

2 strcpy

Прототип функции, назначение и пример использования

int strlen(char *s) возвращает длину строки s без учета нулевого символа '\0\

i n t

п;

char

s[]="Borland С";

n =

s t r l e n ( s ) ; //п=9

char *strcpy(char *а, char *b) копирует всю строку

Ъв строку а и возвращает строку а.

char

s i [ ]="Borland";

 

char

s 2 []="C++";

 

s t r c p y ( s i , s 2 ) ;

 

p u t s ( s i ) ;

//C++

Функция

Прототип функции, назначение

п/п

и пример использования

char *stmcpy(char *а, char *b, unsigned n) копиру­ ет n символов из строки Ъ в строку а и возвраща­

 

 

ет строку а.

 

3

stmcpy

char

si []=nBorlandlf;

 

 

 

char

s2[]="С++";

 

 

 

strncpy(si,s2,2);

//C+rland

 

 

puts(si);

 

 

char *strcat(char *a, char *b) добавляет строку b в

 

 

конец строки а и возвращает строку а.

4

 

char

si[]="BorlandM;

 

strcat

char

s2 []=ИС++И;

 

 

 

strcat(si,s2);

//BorlandC++

 

 

puts(si);

5 stmcat

6 strcmp

char *stmcat(char *a, char *b, unsigned n) добав­ ляет n символов строки b в конец строки а и воз­ вращает строку а.

char si[]="Borland";

char s2[]="C++";

strncat(si,s2,1);

puts(si); //BorlandC

int strcmp(char *a, char *b) попарно сравнивает символы в строках а и Ъ и возвращает разность

кодов первых неравных символов. int п;

n=strcmp ("АВС11, "АВС"); //0 - так как //все символы совпадают n=strcmp("ABC", "ВВС"); //п = 65-66 = -1 //так как код !А !=65, 'В'=66 n=strcmp("АСВ", "АА"); / / п = 67-65 = 2

//так как код fC ,=67, !А ,=65

Функция

п/п

7stmcmp

8strlwr

9 strupr

10 strset

11stmset

12strrev

Прототип функции, назначение и пример использования

int stmcmp(char *а, char *b, unsigned n) попарно сравнивает первые п символов строк а и Ь и воз­

вращаетразностькодов первых неравных символов. int п;

n=strncmp ("ACBD","АСЕЕ",2) ; //0 - //так как первые два символа совпадают char ^strlwr(char *s) преобразует строку s в ниж­

ний регистр (только для латинских букв) и воз­ вращает ее.

char s []="BORLAND"; strlwr(s); puts(s); //borland

char *strupr(char *s) преобразует строку s в верх­

ний регистр (только для латинских букв) и воз­ вращает ее.

char s []=,,borland" ; strupr(s);

put s (s); //BORLAND

char *strset(char *s, char ch) заполняет всю стро­ ку s символами ch и возвращает ее.

char s []="Borland" ; strset (s, 1a 1); puts(s); //aaaaaaa

char *stmset(char *s, char ch, int n) копирует сим­ вол ch в первые n символов строки s и возвраща­

ет ее.

char s []="Borland"; strnset(s,1a',3) ; puts(s); //aaaland

char *strrev(char *s) инвертирует все буквы в строке s и возвращает ее.

char а []="Borland"; strrev(а);

puts(а); //Выводит dnalroB

РЕШЕНИЕ ЗАДАЧ

Задача 1. Заменить в строке все буквы

'о ' на

#include<conio.h>

 

 

 

#include<stdio.h>

 

 

 

#include<string.h>

 

 

 

main()

 

 

 

 

{int

i,n;

 

 

 

 

char

a [50];

 

 

 

 

puts("Введите

строку");

 

 

gets(а); //считываем строку

 

 

n =

strlen(a);

//определяем число символов

 

 

//в

ней

 

 

for(i=0; i<n; i++)

//перебираем все элементы

 

 

 

//массива а

равен

'о1,

if(a[i]==* о 1) //если элемент

a[i]=la l;

//заменяем его

на *а*

 

puts(а); //печатаем преобразованную строку getch() ;

return 0;

}

Задача 2. Подсчитать, сколько раз входит в заданную стро­ ку заданный символ.

#include <stdio.h> #include <conio.h> ttinclude <string.h> main()

{char str[50],a; int i,n,s;

puts("Введите строку:"); gets(str); //считываем строку puts("Введите символ:"); a=getche(); //считываем символ