c程序设计语言笔记4

打印输入中包含特定“模式”或字符串的各行(UNIX程序grep的特例)

#include <stdio.h>

#define MAXLINE 1000	/*输入的最大行长度   */

int getline(char line[],int max);
int strindex(char source[],char searchfor[]);

char pattern[] = "ould";	/*待查找的模式	*/

main()
{
	char line[MAXLINE];
	int found = 0;

	while (getline(line, MAXLINE) > 0)
		if (strindex(line, pattern) >= 0){
			printf("%s", line);
			found++;
		}
	return found;
}

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;
}

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 <stdio.h>
#include <ctype.h>
#define MAXLINE 1000

double atof(char s[]);   /*把字符串s转换为相应的双精度浮点数*/
int getline(char line[], int max);

main()
{
	double sum;
	char line[MAXLINE];

	sum = 0;
	while (getline(line,MAXLINE) > 0)
		printf("\t%g\n", sum += atof(line));
	return 0;

}

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;
}

double atof(char s[])
{
	double val, power;
	int i, sign;

	for(i = 0;isspace(s[i]);i++)
		;
	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.0;
	}
	return sign * val / power;
}

寄存器变量,它所声明的变量在程序中使用的频率较高

register int x;


递归函数实现打印十进制数:

#include <stdio.h>

void printd(int);

main()
{
	int n = -999;
	printd(n);
	getch();
}


void printd(int n)
{
	if (n < 0){
		putchar('-');
		n = -n;
	}
	if (n / 10)
		printd(n / 10);
	putchar(n%10 + '0');

}

快速排序算法:对于给定的数组,从中选出一个元素,以该元素为界将其余的元素划分为两个子集,一个子集中的所有元素都小于该元素,另一个子集中的元素都大于或等于该元素。对这两个子集递归这一过程,当某个子集的元素数小于2时,这个子集不再需要递归。

#include <stdio.h>

void qsort(int v[],int left,int right);
void swap(int v[],int i,int j);

main()
{
	int i, v[7] = {9,5,6,3,1,4,2};
	qsort(v,0,6);
	for(i = 0;i <= 6;i++)
		printf("%d ",v[i]);
	getch();
}

void qsort(int v[],int left,int right)
{
	int i, last;
	
	if (left >= right)/*若数组包含的元素数少于2个*/
		return;	/*不执行任何操作*/
	swap(v, left, (left + right) / 2); /*将划分子集的元素*/
	last = left;	/*移动到v[0]*/
	for (i = left + 1;i <= right;i++) /*划分子集*/
		if (v[i] < v[left])
			swap(v,++last,i);
	swap(v,left,last);	/*恢复划分子集的元素*/
	qsort(v,left,last - 1);
	qsort(v,last+1,right);
}

void swap(int v[],int i,int j)
{
	int temp;

	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

练习4-1 编写函数strrindex返回字符串t在s中最右端出现的位置。

#include <stdio.h>
#include <string.h>

//int strrindex(char s[], char t[]);

main()
{
	char pattern[] = "ould";
	char s[] = "icouldandwouldfindyou";

	printf("%d\n",strrindex(s,pattern));
	getch();
}


/*int strrindex(char s[], char t[])
{
	int i, j, k, pos;
	pos = -1;

	for (i = 0;s[i] != '\0';i++){
		for (j = i, k = 0;t[k] == s[j] && t[k] != '\0';j++,k++)
			;
		if (k > 0 && t[k] == '\0')
			pos = i;
	}
	return pos;

}   */

int strrindex(char s[], char t[])
{
	int i, j, k;

	for (i = strlen(s) - strlen(t);i > 0;i--){
		for (j = i, k = 0;s[j] == t[k] && t[k] != '\0';j++,k++)
			;
		if (k > 0 && t[k] == '\0')
			return i;
	}
	return -1;
}

练习4-2 对atof扩充使之能处理科学表示法。

#include <stdio.h>
#include <ctype.h>

double atof(char s[]);

main()
{
	char s[] = "123.45e6";
	printf("123.45e6 is %e\n",atof(s));
	getch();
}

double atof(char s[])
{
	double val, power;
	int exp, 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.0;
	}
	val = val * sign / power;

	if (s[i] == 'e' || s[i] == 'E'){
		sign = (s[++i] == '-') ? -1 : 1;
		if (s[i] == '+' || s[i] == '-')
			i++;
		for (exp = 0;isdigit(s[i]);i++)
			exp = 10.0 * exp + (s[i] - '0');
		if (sign = 1)
			while(exp-- > 0)
				val *= 10.0;
		else 
			while (exp-- > 0)
				val /= 10.0; /*用val除以10.0而不是乘以0.1是因为0.1无法用二进制精确的表示出来。在大多数机器中,0.1的二进制表示法都比0.1稍微						小一些  */
	}
	return val;

}
练习4-3加入取模运算

#include <stdio.h>
#include <stdlib.h>  /* for  atof() */
#include <ctype.h>
   
#define MAXOP   100  /* max size of operand or operator */
#define NUMBER  '0'  /* signal that a number was found */
#define MAXVAL  100  /* maximum depth of val stack */
#define BUFSIZE 100
 
int getop(char []);

void push(double);
double pop(void);

int getch(void);
void ungetch(int);

int sp = 0;          /* next free stack position */
double val[MAXVAL];  /* value stack */
char buf[BUFSIZE];    /* buffer for ungetch */
int bufp = 0;         /* next free position in buf */

int main(void) 
{ 
    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 '%': 
                op2 = pop(); 
                if(op2) 
                    push((int)pop()%(int)op2); 
                else 
                    printf("\nError: Division by zero!"); 
                break; 
		   case '\n':
               printf("\t%.8g\n", pop());
               break;
           default:
               printf("error: unknown command %s\n", s);
               break;
  
        } 
    } 
    return EXIT_SUCCESS; 
}

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;
    }
}


int getop(char s[]) 
{ 
    #define PERIOD  '.' 
    int i = 0; 
    int c; 
    int next; 
 
    /* Skip whitespace */ 
    while((s[0] = c = getch()) == ' ' || c == '\t') 
        ; 
    s[1] = '\0'; 
 
    /* Not a number but may contain a unary minus. */ 
	 if(!isdigit(c) && c != PERIOD && c != '-') 
        return c;                
	
    if(c == '-') //如果当前读入的c是'-'
    { 
        next = getch(); //判断下一个输入字符next
        if(!isdigit(next) && next != PERIOD) 
        { 
           return c; //如果next不是数字并且不是小数点,则c为操作符 
        } 
        c = next; //否则,既next是数字
    } 
    else 
    { 
        c = getch(); 
    } 
    /*收集整数部分*/
    while(isdigit(s[++i] = c)) //则把c保存到数组s[]中
            c = getch(); 
    if(c == PERIOD)
		/* 收集小数部分*/ 
        while(isdigit(s[++i] = c = getch())) 
                        ; 
    s[i] = '\0'; 
    if(c != EOF) 
        ungetch(c); 
    return NUMBER; 
}  

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;
}

练习4-5 增加sin,cos,exp,pow等操作

#include <stdio.h>
#include <stdlib.h>  // for atof()
#include <ctype.h>
#include <math.h>
#include <string.h>

#define MAXOP 100  /* max size of operator */
#define NUMBER '0' /*signal that a number is founded */
#define NAME 'n'   /* signal that a name is founded */
#define MAXVAL 100 /* maximum depth of val stack */
#define BUFSIZE 100

int getop(char s[]);
void mathfnc(char s[]);
void push(double);
double pop();
int getch();
void ungetch(int);

int sp;  /* top stack position */
double val[MAXVAL];
char buf[BUFSIZE];
double variable[26];
int bufp = 0;  /* next buf position */

main()
{
	int i, type, var = 0;
	double op2, v;
	char s[MAXOP];
	for (i = 0;i < 26;i++)
		variable[i] = 0.0;

	while ((type = getop(s)) != EOF){
		switch(type){
			case NUMBER:
				push(atof(s));
				break;
			case NAME:
				mathfnc(s);
				break;
			case '+':
				push(pop() + pop());
				break;
			case '*':
				push(pop() * pop());
				break;
			case '-':
				op2 = pop();
				push(pop() - op2);
				break;
			case '/':
				op2 = pop();
				if (op2)
					push(pop() / op2);
				else 
					printf("error: zero divisor\n");
				break;
			case '%':
				op2 = pop();
				if(op2)
					push(fmod(pop(),op2));
				else 
					printf("error: zero divisor\n");
				break;
			case '\n':
				if (sp > 0){
					v = pop();
					printf("\t%.8g\n",v);
				}
				break;
			case '=':
				pop();
				if (var >= 'A' && var <= 'Z')
					variable[var - 'A'] = pop();
				break;
			default:
				if (type >= 'A' && type <= 'Z')
					push(variable[type - 'A']);
				else if ('v' == type)
					push(v);
				else 
					printf("error: unknown command %s\n",s);
				break;

		}
		var = type;
	}
	return 0;
}

void mathfnc(char s[])
{
	double op2;

	if (!strcmp(s,"sin"))
		push(sin(pop()));
	else if (!strcmp(s,"cos"))
		push(cos(pop()));
	else if (!strcmp(s,"exp"))
		push(exp(pop()));
	else if (!strcmp(s,"pow")){
		op2 = pop();
		push(pow(pop(),op2));
	}
	else 
		printf("error: %s not support.\n",s);
}

int getop(char s[])
{
	int c, i;

	while ((s[0] = c = getch()) == ' ' || c == '\t')
		;
	s[1] = '\0';
	i = 0;
	if (islower(c)){
		while (islower(s[++i] = c = getch()))
			;
		s[i] = '\0';
		if (c != EOF)
			ungetch(c);     /* went one char too far  */
		if (strlen(s) > 1)
			return NAME;	/* >1 char;it is a NAME	*/
		else 
			return c;		/* it may be a command	*/
	}
	if (!isdigit(c) && c != '.' && c != '-')
		return c;	/* not a number */
	if (c == '-')
		if (isdigit(c = getch()) || c == '.')        /*之前写成c = ‘.’ 造成输入1 2 +\n时出现错误,为什么呢? 以后写成'.' == c就不会出现这样错误								了 */
			s[++i] = c;		/* negative number */
		else{
			if (c != EOF)
				ungetch(c);
			return '-';
		}
	if (isdigit(c))
		while (isdigit(s[++i] = c = getch()))
			;
	if (c == '.')
		while (isdigit(s[++i] = c = getch()))
			;
	s[i] = '\0';
	if (c != EOF)
		ungetch(c);
	return NUMBER;
}

int getch()
{
	return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(char c)
{
	if (bufp >= BUFSIZE)
		printf("ungetch: too many characters\n");
	else 
		buf[bufp++] = c;
}
void push(double c)
{
	if (sp < MAXVAL)
		val[sp++] = c;
	else 
		printf("error: stack is full,cann't push %g\n",c);
}

double pop()
{
	if (sp > 0)
		return val[--sp];
	else 
		printf("error: stack is empty.\n");
		return 0.0;
}

练习4-6增加变量处理的命令

见上

练习4-11在getop函数中不使用ungetch函数,而可以使用一个static类型的内部变量解决该问题



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值