Функции и структура на програмата - 1
Chapter 4 - Functions and Program Structure
4.1 Basics of Functions
4.2 Functions Returning Non-integers
4.3 External Variables
4.4 Scope Rules
4.5 Header Files
Основи на функциите
Пример:
Програма, която търси даден низ във входен текст, разделен на редове
и извежда само редовете, съдържащи дадения низ.
Примерен вход:
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
(Омар Хаям, Рубаят)
Изход за примерния вход:
ebook - The C Programming Language Ritchie & kernighan
-.doc
Ah Love! could you and I with Fate conspire
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
Псевдокод:
while (there's another line)
if (the line contains the pattern)
print it
Решение:
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int max);
int strindex(char source[], char searchfor[]);
char pattern[] = "ould"; /* pattern to search
for */
/* find all lines matching pattern */
int main()
{
char line[MAXLINE];
int found = 0;
while (getline(line, MAXLINE) > 0)
if (strindex(line,
pattern) >= 0) {
printf("%s", line);
found++;
}
return found;
}
/* getline: get line into s, return length */
int getline(char s[], int lim)
{
int c, i;
i = 0;
while (--lim > 0 &&
(c=getchar()) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
/* strindex: return index of t in s, -1 if none
*/
int strindex(char s[], char t[])
{
int i, j, k;
for (i = 0; s[i] != '\0'; i++) {
for (j=i, k=0;
t[k]!='\0' && s[j]==t[k]; j++, k++)
;
if (k > 0
&& t[k] == '\0')
return i;
}
return -1;
}
Функции, които не връщат цяло число
Пример:
Превръщане на низ в число с плаваща запетая.
#include <ctype.h>
/* atof: convert string s to double */
double atof(char s[])
{
double val, power;
int i, sign;
for (i = 0; isspace(s[i]); i++) /*
skip white space */
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val +
(s[i] - '0');
if (s[i] == '.')
i++;
for (power = 1.0; isdigit(s[i]); i++)
{
val = 10.0 * val +
(s[i] - '0');
power *= 10;
}
return sign * val / power;
}
Пример:
Примитивен калкулатор - събера въведените числа.
#include <stdio.h>
#define MAXLINE 100
/* rudimentary calculator */
int main()
{
double sum, atof(char []);
char line[MAXLINE];
int getline(char line[], int max);
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n",
sum += atof(line));
return 0;
}
Външни променливи
Пример:
Калкулатор с вход "полски запис.
(1 - 2) * (4 + 5)
1 2 - 4 5 + *
Стек - FIFO
Псевдокод:
while (next operator or operand is not
end-of-file indicator)
if (number)
push it
else if (operator)
pop operands
do operation
push result
else if (newline)
pop and print top
of stack
else
error
Скелет:
#includes
#defines
function declarations for main
main() { ... }
external variables for push and pop
void push( double f) { ... }
double pop(void) { ... }
int getop(char s[]) { ... }
routines called by getop
Реализация на алгоритъма:
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#define MAXOP 100 /* max size of operand or
operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
void push(double);
double pop(void);
/* reverse Polish calculator */
int main()
{
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) !=
EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
Реализация на функциите push и pop.
#define MAXVAL 100 /* maximum depth of val stack
*/
int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */
/* push: push f onto value stack */
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error:
stack full, can't push %g\n", f);
}
/* pop: pop and return top value from stack */
double pop(void)
{
if (sp > 0)
return val[--sp];
else {
printf("error:
stack empty\n");
return 0.0;
}
}
Реализация на функцията getop.
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getop: get next character or numeric operand
*/
int getop(char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' ||
c == '\t') ;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; /* not a
number */
i = 0;
if (isdigit(c)) /* collect integer
part */
while (isdigit(s[++i] = c = getch()))
;
if (c == '.') /* collect fraction part
*/
while
(isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
Реализация на функциите getch и ungetch.
#define BUFSIZE 100
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) /* get a (possibly pushed-back)
character */
{
return (bufp > 0) ? buf[--bufp] :
getchar();
}
void ungetch(int c) /* push character back on
input */
{
if (bufp >= BUFSIZE)
printf("ungetch:
too many characters\n");
else
buf[bufp++] =
c;
}
Правила за област на видимост
Пример:
in file1:
extern int sp;
extern double val[];
void push(double f) { ... }
double pop(void) { ... }
in file2:
int sp = 0;
ebook - The C Programming Language Ritchie &
kernighan -.doc
double val[MAXVAL];
Заглавни файлове
ebook - The C Programming Language Ritchie & kernighan
-.doc
ebook - The C Programming Language Ritchie & kernighan
-.doc
ebook - The C Programming Language Ritchie & kernighan
-.doc
ebook - The C Programming Language Ritchie & kernighan
-.do
Задачи:
1. Да се напише функция, която проверява дали даден символ се среща
в зададен низ.
2. Да се напише функция, която проверява дали даден символ се среща
в зададен низ и връща индекса му или -1, аке не се среща.
3. Да се напише функция, която проверява колко пъти даден символ се
среща в зададен низ.
4. Да се напише функция, която връща най-често срещащия се символ в
зададен низ.
5. Да се напише програма, която отпечатва честотна диаграма на
срещанията на буквите от латинската азбука в даден текст.
6. Да се напише програма, която форматира даден текст - разделя го
на редове, не по големи от зададено число, без за разкъсва думите.