В Си есть два оператора, предназначенных для увеличения и уменьшения переменных. Оператор инкремента ++ добавляет 1 к своему операнду, а оператор декремента -- вычитает 1.
Необычность операторов ++ и -- в том, что их можно использовать и как префиксные (помещая перед переменной: ++n), и как постфиксные (помещая после переменной: n++) операторы. В обоих случаях значение n увеличивается на 1, но выражение ++n увеличивает n до того, как его значение будет использовано,
а n++ — после того.
а n++ — после того.
Предположим, что n содержит 5, тогда
x = n++;
установит x в значение 5, а
x = ++n;
установит х в значение 6. И в том и другом случае n станет равным 6.
if (c == '\n')
nl++;
nl++;
то безразлично, какой оператор выбрать — префиксный или постфиксный.
Но существуют ситуации, когда требуется оператор вполне определенного типа. В качестве примера, авторы книги предлагают рассмотреть функцию
squeeze(s, с), которая удаляет из строки s все символы, совпадающие с c:
#include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void squeeze(char s[], int с);
int c = 65; /* Символ 'A' */
int main(void)
{
int len = 0;
char line[MAXLINE]; /* текущая строка */
while ((len = getstr(line, MAXLINE)) > 0)
{
squeeze(line, c);
printf("%s", line);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* squeeze: удаляет все с из s */
void squeeze(char s[], int с)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != c)
s[j++] = s[i];
s[i] = '\0';
}
#include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void squeeze(char line[], int symbol);
int main(void)
{
int len = 0;
char line[MAXLINE]; /* текущая строка */
int c = 65; /* Символ 'A' */
while ((len = getstr(line, MAXLINE)) > 0)
{
squeeze(line, c);
printf("%s", line);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* squeeze: удаляет все с из s */
void squeeze(char s[], int symb)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != symb)
s[j++] = s[i];
s[i] = '\0';
}
if (s[i] != с) {
s[j] = s[i];
j++;
}
squeeze(s, с), которая удаляет из строки s все символы, совпадающие с c:
#include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void squeeze(char s[], int с);
int c = 65; /* Символ 'A' */
int main(void)
{
int len = 0;
char line[MAXLINE]; /* текущая строка */
while ((len = getstr(line, MAXLINE)) > 0)
{
squeeze(line, c);
printf("%s", line);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* squeeze: удаляет все с из s */
void squeeze(char s[], int с)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != c)
s[j++] = s[i];
s[i] = '\0';
}
#include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void squeeze(char line[], int symbol);
int main(void)
{
int len = 0;
char line[MAXLINE]; /* текущая строка */
int c = 65; /* Символ 'A' */
while ((len = getstr(line, MAXLINE)) > 0)
{
squeeze(line, c);
printf("%s", line);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* squeeze: удаляет все с из s */
void squeeze(char s[], int symb)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != symb)
s[j++] = s[i];
s[i] = '\0';
}
Каждый раз, когда встречается символ, отличный от с, он копируется в текущую j-ю позицию, и только после этого переменная j увеличивается на 1, подготавливаясь таким образом к приему следующего символа. Это в точности совпадает со следующими действиями:
if (s[i] != с) {
s[j] = s[i];
j++;
}
if (с == '\n' ) {
s[i] = с;
++i;
}
s[i] = с;
++i;
}
можно переписать более компактно:
if (с == '\n' )
s[i++] = с;
s[i++] = с;
В качестве третьего примера рассматривается функция strcut(s, t), которая строку t помещает в конец строки s. Предполагается, что в s достаточно места, чтобы разместить там суммарную строку. strcut написана так, что она не возвращает никакого результата. На самом деле библиотечная strcat возвращает указатель на результирующую строку.
#include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void strcut(char line[], char new_line[]);
int main(void)
{
int len = 0;
char line[MAXLINE]; /* текущая строка */
char new_line[] = "This is the end!";
while ((len = getstr(line, MAXLINE)) > 0)
{
strcut(line, new_line);
printf("%s", line);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* strcut: помещает t в конец s; s достаточно велика */
void strcut(char s[], char t[])
{
int i, j;
i = j = 0;
while (s[i] != '\0') /* находим конец s */
i++;
while ((s[i++] = t[j++]) != '\0') /* копируем t */
;
}
При копировании очередного символа из t в s постфиксный оператор ++ применяется и к i, и к j, чтобы на каждом шаге цикла переменные i и j правильно отслеживали позиции перемещаемого символа.
Комментариев нет:
Отправить комментарий