книги / Язык Си
..pdfЕсли вызов макроса имеет вид 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(); //считываем символ