星海's Blog

老头初学编程
C程序设计语言(第二版)课后习题答案 1-3 章
多种类型菱形打印(初学代码,以后删除)

C程序设计语言(第二版)课后习题答案 4-6 章

星海 posted @ 2011年1月09日 00:17 in C代码 , 1815 阅读
/*
 * =====================================================================================
 *
 *       Filename:  4-1.c
 *
 *    Description:
 *    编写函数strrindex(s,t),他返回字符串t在s中最右边出现的位置。如果s中不包含t,则返回-1
 *
 *        Version:  1.0
 *        Created:  2011年01月08日 16时24分12秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Sd44 (), sd44sd44@yeah.net
 *       Homepage:  http://sd44.is-programmer.com
 *
 * ===================================================================================== 
 */

#include	<stdio.h>
int strrindex(char s[], char t[])
{
	int i, j, k, subnum = -1;  

	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')
			subnum = i;
	}  
	return subnum;

}

int main(void)
{
	char a[] = "wo ha woai ni";
	char b[] = "wo";
	printf("%d\n", strrindex(a, b));
	return 0;

}

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

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

	if (s[i] == 'e' || s[i] == 'E')
		++i;
	if (s[i] == '+') {
		++i;
		sign = 1;
	}
	if (s[i] == '-') {
		++i;
		sign = -1;
	}

	for (expnum = 0; isdigit(s[i]); ++i)
		expnum = 10 * expnum + (s[i] - '0');
	val = val * pow(10, sign * expnum);
	return val;
}

int main(void)
{
	char a[] = "123.45e-2";
	printf("%f\n", atof(a));
	return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>

#define MAXOP      100
#define NUMBER       0
/* 4-6 these are new for this exercise*/
#define IDENTIFIER   1
#define ENDSTRING    2
/* 4-6 end of new stuff */
#define TRUE         1
#define FALSE        0
#define MAX_ID_LEN  32
#define MAXVARS     30

/* 
The new additions deal with adding variables to the calculator.

  If the identifier is recognised as one of the supported mathematical 
  functions then that function from the library is called. If the 
  identifier is not one of the supported functions, even if it is a
  valid function from math.h it is ignored.
  
  This is a class 1 solution as it uses structures which are not 
  introduced until Chapter 6. This allows the use of "normal" names for
  variables rather than the suggested single letter though any 
  identifier is limited to 31 characters.
    
  The main changes are:
      
    1. The introduction of two more define values (IDENTIFIER, 
       ENDSTRING) along with associated cases in the switch statement. 
    2. Getop has also been changed to deal with reading in alphabetical 
       characters and coping with the '=' sign.
    3. A structure to hold the variable name and value.
    4. Another case in the switch statement to deal with the '=' sign.
    5. Altering the clearStack function to clear the array of structs as
       well as the stack.
    6. The '<' operator now prints the last accessed variable.
        
  Improvements:
  The code could be made class 0 by the use of "parallel" arrays for the
  names and values rather than a struct but this would be messy and is 
  the situation that structs were made for.
  The use of a binary tree together with dynamically allocated memory
  would allow the arbitrary limit of 30 variables to be avoided. This 
  would still be a class 1 solution. 
         
  This is exercise 4-6 from Kernighan & Ritchie, page 79.               
*/

/* 4-6 this is new for this program */
struct varType {
	char name[MAX_ID_LEN];
	double val;
};
/* 4-6 End of new stuff */

int Getop(char s[]);
void push(double val);
double pop(void);
void showTop(void);
void duplicate(void);
void swapItems(void);

/* 4-6 this is new for this program */
/* Changed clearStack(void) to clearStacks(struct varType var[])*/
void clearStacks(struct varType var[]);
void dealWithName(char s[], struct varType var[]);
void dealWithVar(char s[], struct varType var[]);

int pos = 0;
struct varType last;

/* 4-6 End of new stuff */

int main(void)
{
	int type;
	double op2;
	char s[MAXOP];
	struct varType var[MAXVARS];

	/* Use the new function here */
	clearStacks(var);

	while ((type = Getop(s)) != EOF) {
		switch (type) {
		case NUMBER:
			push(atof(s));
			break;
		case IDENTIFIER:
			dealWithName(s, var);
			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("\nError: division by zero!");
			break;
		case '%':
			op2 = pop();
			if (op2)
				push(fmod(pop(), op2));
			else
				printf("\nError: division by zero!");
			break;
		case '?':
			showTop();
			break;
		case '#':
			duplicate();
			break;
		case '~':
			swapItems();
			break;
		case '!':
			clearStacks(var);
			break;
		case '\n':
			printf("\n\t%.8g\n", pop());
			break;
			/* 4-6 this is new for this program */
		case ENDSTRING:
			break;
		case '=':
			pop();
			var[pos].val = pop();
			last.val = var[pos].val;
			push(last.val);
			break;
		case '<':
			printf("The last variable used was: %s (value == %g)\n",
			       last.name, last.val);
			break;
			/* 4-6 End of new stuff */
		default:
			printf("\nError: unknown command %s.\n", s);
			break;
		}
	}
	return EXIT_SUCCESS;
}

#define MAXVAL 100

int sp = 0;			/* Next free stack position. */
double val[MAXVAL];		/* value stack. */

/* push: push f onto stack. */
void push(double f)
{
	if (sp < MAXVAL)
		val[sp++] = f;
	else
		printf("\nError: 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("\nError: stack empty\n");
		return 0.0;
	}
}

void showTop(void)
{
	if (sp > 0)
		printf("Top of stack contains: %8g\n", val[sp - 1]);
	else
		printf("The stack is empty!\n");
}

/*
Alternatively:
void showTop(void)
{
double item = pop();
printf("Top of stack contains: %8g\n", item);
push(item);
}  
*/

void duplicate(void)
{
	double temp = pop();

	push(temp);
	push(temp);
}

void swapItems(void)
{
	double item1 = pop();
	double item2 = pop();

	push(item1);
	push(item2);
}

/* 4-6 this is new for this program */
/* Altered to clear both the main stack and that of the variable
structure */
void clearStacks(struct varType var[])
{
	int i;

	/* Clear the main stack by setting the pointer to the bottom. */
	sp = 0;

	/* Clear the variables by setting the initial element of each name
	   to the terminating character. */
	for (i = 0; i < MAXVARS; ++i) {
		var[i].name[0] = '\0';
		var[i].val = 0.0;
	}
}

/* a string/name may be either a maths function or a variable */
void dealWithName(char s[], struct varType var[])
{
	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));
	}
	/* Finally if it isn't one of the supported maths functions we have a 
	   variable to deal with. */
	else {
		dealWithVar(s, var);
	}
}

/* Our identifier is not one of the supported maths function so we have 
   to regard it as an identifier. */
void dealWithVar(char s[], struct varType var[])
{
	int i = 0;

	while (var[i].name[0] != '\0' && i < MAXVARS - 1) {
		if (!strcmp(s, var[i].name)) {
			strcpy(last.name, s);
			last.val = var[i].val;
			push(var[i].val);
			pos = i;
			return;
		}
		i++;
	}

	/* variable name not found so add it */
	strcpy(var[i].name, s);
	/* And save it to the last variable */
	strcpy(last.name, s);
	push(var[i].val);
	pos = i;
}

/* 4-6 End of new stuff */

int getch(void);
void unGetch(int);

/* Getop: get next operator or numeric operand. */
int Getop(char s[])
{
	int i = 0;
	int c;
	int next;

	/* Skip whitespace */
	while ((s[0] = c = getch()) == ' ' || c == '\t') {
		;
	}
	s[1] = '\0';

	if (isalpha(c)) {
		i = 0;
		while (isalpha(s[i++] = c)) {
			c = getch();
		}
		s[i - 1] = '\0';
		if (c != EOF)
			unGetch(c);
		return IDENTIFIER;
	}

	/* Not a number but may contain a unary minus. */
	if (!isdigit(c) && c != '.' && c != '-') {
		/* 4-6 Deal with assigning a variable. */
		if ('=' == c && '\n' == (next = getch())) {
			unGetch('\0');
			return c;
		}
		if ('\0' == c)
			return ENDSTRING;

		return c;
	}

	if (c == '-') {
		next = getch();
		if (!isdigit(next) && next != '.') {
			return c;
		}
		c = next;
	} else {
		c = getch();
	}

	while (isdigit(s[++i] = c)) {
		c = getch();
	}
	if (c == '.') {		/* Collect fraction part. */
		while (isdigit(s[++i] = c = getch())) ;
	}
	s[i] = '\0';
	if (c != EOF)
		unGetch(c);
	return NUMBER;
}

#define BUFSIZE 100

int buf[BUFSIZE];
int bufp = 0;

/* Getch: get a ( possibly pushed back) character. */
int getch(void)
{
	return (bufp > 0) ? buf[--bufp] : getchar();
}

/* unGetch: push character back on input. */
void unGetch(int c)
{
	if (bufp >= BUFSIZE)
		printf("\nUnGetch: too many characters\n");
	else
		buf[bufp++] = c;
}
#include <stdio.h>
#include	<string.h>

#define	BUFSIZE 100		/*  */
char buf[BUFSIZE];
int bufp = 0;

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

void ungetch(int c)
{
	if (bufp >= BUFSIZE)
		printf("ungetch: too many character\n");
	else
		buf[bufp++] = c;
}

void ungets(char s[])
{
	size_t i = strlen(s);
	while (i--)
		ungetch(s[i]);
}

int main(void)
{
	int c;
	char s[] = "wo ai bei jing tian an men";
	ungets(s);
	while ((c = getch()) != EOF)
		putchar(c);
	return 0;
}
#include <stdio.h>

int bufp = EOF;

int getch(void)
{
	int temp;
	if (bufp != EOF) {
		temp = bufp;
		bufp = EOF;
	} else
		temp = getchar();
	return temp;
}

void ungetch(int c)
{
	bufp = c;
}

int main(void)
{
	char c = 's';
	ungetch(c);
	putchar(getch());
	return 0;
}
//此程序做完后,参考网上答案,自己写的函数不够规范,两个函数都不完整,必须借助于另一个函数来实现一个功能
// 例如http://www.dnbcw.com/biancheng/c/leku175858.html 中所介绍的,'\0'是直接在单个函数中通过 if (value < (unsigned) base) else 加入的。。。

#include	<stdio.h>
void _itoa(int n, char *s)
{
	if (n / 10)
		_itoa(n / 10, s - 1);
	*s = n % 10 + '0';
}

void itoa(int n, char *s)
{
	int x, digit = 0;	/*digit为整数n的位数 */

	if (n < 0) {		/* 如果n为负数,数组首位为 '-' */
		n = -n;
		*s++ = '-';
	}

	x = n;			/* 求n的位数digit */
	do {
		++digit;
	} while (x /= 10);

	_itoa(n, s + digit - 1);	/* 递归调用_itoa */
	*(s + digit) = '\0';	/* 转换完成后,结尾 */
}

int main(void)
{
	char a[10];
	itoa(-231456, a);
	printf("%s\n", a);                 
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  4-13.c
 *
 *    Description:  reverse(s)递归版本
 *
 *        Version:  1.0
 *        Created:  2011年01月13日 13时20分49秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include	<stdio.h>
#include	<string.h>
void swap(char *a, char *b)
{
	char temp;
	temp = *a;
	*a = *b;
	*b = temp;
}

void reverse(char *s, unsigned int len)
{
	if (len <= 1)
		return;
	swap(s, s + len - 1);
	reverse(s + 1, len - 1 - 1);
}

int main(int argc, char *argv[])
{
	char a[] = "tian an men, wo ai ni";
	reverse(a, strlen(a));
	printf("%s\n", a);
	return 0;
}
#define swap(t,x,y) do{t z=x;x=y;y=z;}while(0)

do while既保持良好的程序块格式,又不会因为 ;号而影响易读性

 

#include	<stdio.h>
#include	<ctype.h>
#include	"getch.c"

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

int getfloat(double *pn)
{
	int c, sign, flag = 0;
	double power = 1.0;

	while (isspace(c = getch())) ;
	if (!isdigit(c) && c != EOF && c != '+' && c != '-' && c != '.') {
		ungetch(c);
		return 0;
	}
	sign = (c == '-') ? -1 : 1;
	if (c == '+' || c == '-') {
		flag = c;
		c = getch();
	}
	if (!isdigit(c) && c != '.') {
		ungetch(c);
		if (flag)
			ungetch(flag);
		return 0;
	}

	for (*pn = 0.0; isdigit(c); c = getch())
		*pn = 10.0 * *pn + (c - '0');

	if (c == '.')
		while (isdigit(c = getch())) {
			*pn = 10.0 * *pn + (c - '0');
			power *= 10.0;
		}
	*pn *= sign;
	*pn /= power;

	if (c != EOF)
		ungetch(c);
	return c;
}

 

/*
 *       Filename:  5-3.c
 *
 *    Description:  用指针实现strcat(s,t)
 *
 *        Version:  1.0
 *        Created:  2011年01月14日 00时10分37秒
 *
 * ==========================================================================
 */
#include	<stdio.h>

char *strcat(char *s, char *t)
{
	char *p = s;
	while (*s++) ;
	s--;
	while (*s++ = *t++) ;
	return p;
}

int main(void)
{
	char a[100] = " lao po,jia you. ";
	char b[] = " zi mo, ye jia you ";
	printf("%s \n", strcat(a, b));
	return 0;
}

 

/*
 * ==========================================================================
 *
 *       Filename:  5-4.c
 *
 *    Description:  strend(s,t),如果字符串t出现在字符串s尾部,返回1
 *
 *        Version:  1.0
 *        Created:  2011年01月14日 01时09分42秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include	<stdio.h>
#include	<string.h>
int strend(char *s, char *t)
{
	size_t x, y;
	x = strlen(s);
	y = strlen(t);

	for (; x > 0 && y > 0 && *(s + x - 1) == *(t + y - 1); x--, y--) ;
	if (y == 0)
		return 1;
	else
		return 0;
}

int main(void)
{
	char a[] = "nasa damn";
	char b[] = "damn";
	printf("%d\n", strend(a, b));
	return 0;
}

 

// strncmp的创建有点费时
#include	<stdio.h>

void strncpy2(char *s, char *t, size_t n)
{
	while (n--)
		*s++ = *t++;
	*s = '\0';
}

char *strncat(char *s, char *t, size_t n)
{
	char *p = s;
	while (*s++) ;
	s--;
	while (n--)
		*s++ = *t++;
	return p;
}

int strncmp(char *s, char *t, size_t n)
{
	while (n--) {
		if (*s == '\0' || *t == '\0')	/*防止指针越界 */
			return *s - *t;
		if (*s++ != *t++)
			return *--s - *--t;	/* 返回不相等字符的差 */
	}
	return 0;
}

int main(void)
{
	char a[100] = " lao po,jia you. ";
	char b[] = "zi mo, ye jia you ";
	printf("%s \n", strncat(a, b, 5));
	strncpy2(a, b, 5);
	printf("%s \n", a);
	printf("%d\n", strncmp(a, b, 8));

	char c[5] = "haha ";
	char d[5] = "haha";
	printf("%d\n", strncmp(c, d, 6));
	return 0;
}

 

#include	<stdio.h>
#include	<string.h>
#include	"getch.c"

#define	MAXLINES 5000		/*  */
#define	MAXLEN 1000		/*  */

int getline2(char *, int);
int readlines(char lineptr[][MAXLEN], int maxlines)
{				/* 二维数组做形参,第二维必须是常量 */
	int len, nlines = 0;

	while ((len = getline2(lineptr[nlines], MAXLEN)) > 0)	/* 注意此时getline2的形参 */
		if (nlines >= MAXLINES)
			return -1;
		else {
			lineptr[nlines][len - 1] = '\0';	/* 去掉换行符 */
			nlines++;
		}
	return nlines;
}

void writelines(char *lineptr[], int nlines)
{
	int i;

	for (i = 0; i < nlines; i++)
		printf("%s\n", lineptr[i]);
}

void qsort2(char *v[], int left, int right)
{
	int i, last;
	void swap(char *v[], int i, int j);

	if (left >= right)
		return;
	swap(v, left, (left + right) / 2);
	last = left;
	for (i = left + 1; i <= right; i++)
		if (strcmp(v[i], v[left]) < 0)
			swap(v, ++last, i);
	swap(v, left, last);
	qsort2(v, left, last - 1);
	qsort2(v, last + 1, right);
}

void swap(char *v[], int i, int j)
{
	char *temp;
	temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}

int main(int argc, char *argv[])
{
	int nlines, backnlines;
	char linearr[MAXLINES][MAXLEN];
	char *lineptr[MAXLINES];

	if ((nlines = readlines(linearr, MAXLINES)) >= 0) {
		backnlines = nlines;
		while (backnlines--)
			lineptr[backnlines] = linearr[backnlines];
		qsort2(lineptr, 0, nlines - 1);
		writelines(lineptr, nlines);
		return 0;
	} else {
		printf("error: input too big to sort\n");
		return 1;
	}
}				/* ----------  end of function main  ---------- */

int getline2(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';
	return i;
}

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter