星海's Blog

老头初学编程

CPP第五版 课后题

 


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

#define MAXNUM 19		/* 球员数 */
#define MAXNAMECH 20		/* 名字最大字符树 */
#define MAXCHAR 80		/* 棒球队一行中最多字符数 */

struct nine {
	char first[MAXNAMECH];
	char last[MAXNAMECH];
	int gp;			/* 出场次数 */
	int ab;			/* 击中数 */
	int tob;		/* 走垒数 */
	int rbi;		/* 跑点数 */
	double sucrate;		/* 成功率 */
};

/*-----------------------------------------------------------------------------
 *  思路:用一个临时字符串存放棒球队信息文件中一行的字符数据
 *  调用sscanf将字符转换为struct结构中相应数据项
 *-----------------------------------------------------------------------------*/

int main(void)
{
	char line[MAXCHAR];
	int num;
	int tmpgp, tmpab, tmptob, tmprbi;	/* 临时存放结构数据 */

	struct nine temp[MAXNUM];
	memset(temp, 0, sizeof(struct nine) * MAXNUM);

	FILE *fp;		/* input-file pointer */
	char *fp_file_name = "nines.dat";	/* input-file name    */

	fp = fopen(fp_file_name, "r");
	if (fp == NULL) {
		fprintf(stderr, "couldn't open file '%s'; %s\n",
			fp_file_name, strerror(errno));
		exit(EXIT_FAILURE);
	}
	while (fgets(line, MAXCHAR - 1, fp) != NULL) {
		sscanf(line, "%d", &num);
		sscanf(line, "%*d %[^ ] %[^ ] %d %d %d %d", temp[num].first,
		       temp[num].last, &tmpgp, &tmpab, &tmptob, &tmprbi);
		temp[num].gp += tmpgp;
		temp[num].ab += tmpab;
		temp[num].tob += tmptob;
		temp[num].rbi += tmprbi;
	}

	puts("号码  1stname  lastname  上场次数  击中数  走垒数  跑点数  成功率\n");
	for (num = 0; num < MAXNUM; num++) {
		if (temp[num].gp != 0)
			temp[num].sucrate = (float)temp[num].ab / temp[num].gp;
		printf
		    ("%-4d  %-8s  %-8s  %-8d  %-6d  %-6d  %-6d  %.2f\n",
		     num, temp[num].first, temp[num].last, temp[num].gp,
		     temp[num].ab, temp[num].tob, temp[num].rbi,
		     temp[num].sucrate);

	}

	if (fclose(fp) == EOF) {	/* close input file   */
		fprintf(stderr, "couldn't close file '%s'; %s\n",
			fp_file_name, strerror(errno));
		exit(EXIT_FAILURE);
	}
	return 0;
}

 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define ID_MASK     0xFF
#define SIZE_MASK   0x7F00
#define LEFT        0x00000
#define CENTER      0x08000
#define RIGHT       0x10000
#define ALIGN_MASK  0x18000
#define REGULAR     0x00000
#define BOLD        0x20000
#define ITALIC      0x40000
#define UNDERLINE   0x80000
#define STYLE_MASK  0xE0000
#define SIZE_SHIFT  8
typedef unsigned long font;

char do_menu(font * f);
char get_choice(const char *);
void show_menu(void);
void show_font(font f);
void eatline(void);
void get_id(font * f);
void get_size(font * f);
void get_align(font * f);

int main(void)
{
	font sample = 1 | (12 << SIZE_SHIFT) | LEFT | ITALIC;

	while (do_menu(&sample) != 'q')
		continue;
	puts("Bye!");
	return 0;
}

char do_menu(font * f)
{
	char response;

	show_font(*f);
	show_menu();
	response = get_choice("fsabiuq");
	switch (response) {
	case 'f':
		get_id(f);
		break;
	case 's':
		get_size(f);
		break;
	case 'a':
		get_align(f);
		break;
	case 'b':
		*f ^= BOLD;
		break;
	case 'i':
		*f ^= ITALIC;
		break;
	case 'u':
		*f ^= UNDERLINE;
		break;
	case 'q':
		break;
	default:
		fprintf(stderr, "menu problem\n");
	}

	return response;
}

char get_choice(const char *str)
{
	char ch;

	ch = getchar();
	ch = tolower(ch);
	eatline();
	while (strchr(str, ch) == NULL) {
		printf("Please enter one of the following: %s\n", str);
		ch = tolower(getchar());
		eatline();
	}
	return ch;
}

void eatline(void)
{
	while (getchar() != '\n')
		continue;
}

void show_menu(void)
{
	puts("f)change font    s)change size    a)change alignment");
	puts("b)toggle bold    i)toggle italic  u)toggle underline");
	puts("q)quit");
}

void show_font(font f)
{
	printf("\n%4s %4s %9s %3s %3s %3s\n",
	       "ID", "SIZE", "ALIGNMENT", "B", "I", "U");
	printf("%4ld %4ld", f & ID_MASK, (f & SIZE_MASK) >> SIZE_SHIFT);
	switch (f & ALIGN_MASK) {
	case LEFT:
		printf("%7s", "left");
		break;
	case RIGHT:
		printf("%7s", "right");
		break;
	case CENTER:
		printf("%7s", "center");
		break;
	default:
		printf("%7s", "unknown");
		break;
	}
	printf("%8s %3s %3s\n\n", (f & BOLD) == BOLD ? "on" : "off",
	       (f & ITALIC) == ITALIC ? "on" : "off",
	       (f & UNDERLINE) == UNDERLINE ? "on" : "off");
}

void get_id(font * f)
{
	int id;

	printf("Enter font ID (0-255): ");
	scanf("%d", &id);
	id = id & ID_MASK;
	*f |= id;
	eatline();
}

void get_size(font * f)
{
	int size;

	printf("Enter font size (0-127): ");
	scanf("%d", &size);
	*f |= (size << SIZE_SHIFT) & SIZE_MASK;
	eatline();
}

void get_align(font * f)
{
	puts("Select alignment:");
	puts("l)left   c)center   r)right");
	switch (get_choice("lcr")) {
	case 'l':
		*f &= ~ALIGN_MASK;
		*f |= LEFT;
		break;
	case 'c':
		*f &= ~ALIGN_MASK;
		*f |= CENTER;
		break;
	case 'r':
		*f &= ~ALIGN_MASK;
		*f |= RIGHT;
		break;
	default:
		fprintf(stderr, "alignment problem\n");
	}
}

 

C初级常见错误

 

char a[10];
怎么给这个数组赋值呢?
1、定义的时候直接用字符串赋值
char a[10]="hello";
注意:不能先定义再给它赋值,如char a[10]; a[10]="hello";这样是错误的!
2、对数组中字符逐个赋值
char a[10]={'h','e','l','l','o'};
3、利用strcpy
char a[10]; strcpy(a, "hello");

易错情况:
1、char a[10]; a[10]="hello";//一个字符怎么能容纳一个字符串?况且a[10]也是不存在的!
2、char a[10]; a="hello";//这种情况容易出现,a虽然是指针,但是它已经指向在堆栈中分配的10个字符空间,现在这个情况a又指向数据区中的hello常量,这里的指针a出现混乱,不允许!

还有:不能使用关系运算符“==”来比较两个字符串,只能用strcmp() 函数来处理。


C语言的运算符根本无法操作字符串。在C语言中把字符串当作数组来处理,因此,对字符串的限制方式和对数组的一样,特别是,它们都不能用C语言的运算符进行复制和比较操作。
直接尝试对字符串进行复制或比较操作会失败。例如,假定str1和str2有如下声明:

char str1[10], str2[10];

利用=运算符来把字符串复制到字符数组中是不可能的:

str1 = "abc";     /*** WRONG ***/

str2 = str1;       /*** WRONG ***/

C语言把这些语句解释为一个指针与另一个指针之间的(非法的)赋值运算。但是,使用=初始化字符数组是合法的:

char str1[10] = "abc";

这是因为在声明中,=不是赋值运算符。

试图使用关系运算符或判等运算符来比较字符串是合法的,但不会产生预期的结果:

if (str1==str2) ...    /*** WRONG ***/

这条语句把str1和str2作为指针来进行比较,而不是比较两个数组的内容。因为str1和str2有不同的地址,所以表达式str1 == str2的值一定为0。

 

 
下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
 
  是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。

 

多种类型菱形打印(初学代码,以后删除)

 

/*
 * =====================================================================================
 *       Filename:  diamond-1.c
 *    Description:  编写函数diamond打印一个菱形
 *			问题摘自 http://learn.akae.cn/media/ch06s05.html
 * =====================================================================================
 */

#include	<stdio.h>
#include	<stdlib.h>

void diamond(int n, char x)
{
	if (n % 2 == 0) {
		printf("wrong number\n");
		return;
	}

	int i, j;

	for (i = (-n / 2); i < (n / 2 + 1); ++i) {
		for (j = 0; j < n; ++j) {
			if (j < 2 * abs(i)) {
				if (j % 2 == 0)
					printf(" ");
				else
					printf("\t");
			} else
				printf("%c\t", x);
		}
		printf("\n");
	}

}

int main(void)
{
	diamond(5, '&');
	return 0;
}

 

/*
 * =====================================================================================
 *       Filename:  diamond-2.c
 *    Description:  打印如下所示的菱形,创建一个函数diamond2();
 *
    A
   BBB
  CCCCC
 DDDDDDD
  CCCCC
   BBB
    A
 *        Created:  2011年01月10日 23时45分54秒
 * =====================================================================================
 */
#include	<stdio.h>
#include	<stdlib.h>

void diamond2(int n)
{
// 因为要显示大写字母,范围在A-Z,所以n的取值范围为 3——2*26-1=51
	if (n % 2 == 0 && n < 3 && n >= 51) {
		printf("Wrong Number\n");
		return;
	}

	int i, j, k, charx;
	char x = 'A';

	for (i = n / 2; i > -(n / 2 + 1); --i) {
		for (j = 0; j < abs(i); ++j)
			printf(" ");
//当i大于0时,字符A先输出再自增:x++。 否则,--x-1。
		if (i >= 0)
			charx = x++;
		else
			charx = --x - 1;
		for (k = 0; k < n - 2 * abs(i); ++k) {
			printf("%c", charx);
		}
		printf("\n");
	}
}

int main(void)
{
//      测试最大菱形
	diamond2(51);
	return 0;
}

 

/*
 * ==========================================================================
 *
 *    Description:
 *    编写一个程序,读取输入,直到读了10个字符串或者遇到EOF。这个程序可以为用户提供一个有5个选项的菜单:

 1. 输出初始化字符串列表\n\
 2. 按ascii码顺序输出字符串\n\
 3. 按长度递增输出字符串\n\
 4. 按字符串中第一个单词的长度输出字符串\n\
 5. 退出\n
 *
 *        Version:  1.0
 *        Created:  2011年01月28日 00时17分41秒
 *       Revision:  none
 *       Compiler:  gcc
 * ==========================================================================
 */

//全用的选择排序算法
//尤其注意136行,不能是 if (strlen(v[i]) - strlen(v[j]) >
//0),必须是strlen(v[i]) >
//strlen(v[j]),因为strlen返回unsigned值,unsigned值相减返回unsigned值
//

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

#define MAXLINE 10		/* 最多输入字符串个数 */
#define MAXLEN 50		/* 字符串最大字符数 */

void menu(void);		/* 菜单显示程序 */
void prall(char *v[], int n);	/* 打印所有字符串 */
void compascii(char *s);	/* 按ascii码顺序输出字符串 */
void complen(char *v[], size_t lim);	/* 按字符串长度递增输出字符串 */
int cmpwd(char *s);		/* 计算单个字符串中第一个单词的长度 */
void compcmp(char *v[], size_t lim);	/* 按第一个长度排列所有字符串 */

int main(void)
{
	bool flags = true;	/* 菜单“退出”标记 */
	int c, i, j;
	size_t linenum = 0;	/* 实际输入的行数 */
	char a[MAXLINE][MAXLEN] = { 0 };
	char *p[MAXLINE];

	printf
	    ("请输入不超过10个字符串,每行字符串以换行符结尾\n");

	for (i = 0; i < MAXLINE; i++) {
		++linenum;
		j = 0;
		while (((c = getchar()) != '\n') && c != EOF && j < MAXLEN - 1)
			a[i][j++] = c;
		a[i][j] = '\0';
		if (c == EOF)
			break;
	}

	while (flags) {
		for (i = 0; i < linenum; i++)
			p[i] = a[i];
		menu();
		switch (c = getchar()) {
		case '1':
			prall(p, linenum);
			break;
		case '2':
			for (i = 0; i < linenum; ++i)
				compascii(a[i]);
			break;
		case '3':
			complen(p, linenum);
			prall(p, linenum);
			break;
		case '4':
			compcmp(p, linenum);
			prall(p, linenum);
			break;
		case '5':
			flags = false;
			break;
		default:
			printf
			    ("\n\n\n请输入1-5选择您要的功能,按5键推出\n");
			break;
		}
		while (getchar() != '\n') ;	/* 清除多余的回车符 */
	}

	return 0;
}

void menu(void)
{
	printf("按键1-5选择相应菜单\n\
1. 输出初始化字符串列表\n\
2. 按ascii码顺序输出字符串\n\
3. 按长度递增输出字符串\n\
4. 按字符串中第一个单词的长度输出字符串\n\
5. 退出\n");
}

void prall(char *v[], int n)
{

	int i;
	for (i = 0; i < n; i++) {
		printf("%s\n", v[i]);
	}
}

void compascii(char *s)
{
	char a[MAXLEN];
	int i, j, k;
	char temp;
	for (i = 0; i < MAXLEN - 1 && s[i] != '\0'; i++)
		a[i] = s[i];
	for (j = 0; j < i - 1; j++)
		for (k = j + 1; k < i; k++)
			if (a[j] > a[k]) {
				temp = a[j];
				a[j] = a[k];
				a[k] = temp;
			}
	a[i] = '\0';
	printf("%s\n", a);
}

void complen(char *v[], size_t lim)
{
	int i, j;
	char *temp;
	for (i = 0; i < lim - 1; i++)
		for (j = i + 1; j < lim; j++)
			if (strlen(v[i]) > strlen(v[j])) {
				temp = v[i];
				v[i] = v[j];
				v[j] = temp;
			}
}

int cmpwd(char *s)
{
	size_t num = 0;
	while (*s)
		if (!isspace(*s++))
			num++;
		else
			break;
	return num;
}

void compcmp(char *v[], size_t lim)
{
	int i, j;
	char *temp;
	for (i = 0; i < lim - 1; i++)
		for (j = i + 1; j < lim; j++)
			if (cmpwd(v[i]) > cmpwd(v[j])) {
				temp = v[i];
				v[i] = v[j];
				v[j] = temp;
			}
}

 

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

/*
 * =====================================================================================
 *
 *       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;
}

 

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

K&R C 课后题答案,有不完善的地方还请诸位大虾多多指评!

/*
 * ==========================================================================
 *
 *       Filename:  1-6-7.c
 *
 *    Description:  验证表达式getchar()!=EOF 的值是0还是1
 *		    编写一个打印EOF值的程序
 *
 *        Version:  1.0
 *        Created:  2010年12月29日 13时07分03秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

int main(void)
{
	printf("%d\n", getchar() != EOF);
	printf("%d\n", EOF);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-8.c
 *
 *    Description:  编写一个统计空格、制表符与换行符个数的程序
 *
 *        Version:  1.0
 *        Created:  2010年12月29日 13时12分21秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

int main(void)
{
	int c;
	int snum, tnum, nnum;

	snum = tnum = nnum = 0;

	while ((c = getchar()) != EOF) {
		if (c == ' ')
			++snum;
		if (c == '\t')
			++tnum;
		if (c == '\n')
			++nnum;
	}
	printf
	    ("您所输入的字符串中\n 共有空格 %d 个,制表符 %d 个, 换行符 %d 个\n ",
	     snum, tnum, nnum);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-9.c
 *
 *    Description:  将输入复制到输出,并将其中连续的多个空格用一个空格代替
 *
 *        Version:  1.0
 *        Created:  2010年12月29日 13时20分54秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

int main(void)
{
	int flags = 1;
	int c;

	while ((c = getchar()) != EOF) {
		if (c == ' ') {
			if (flags == 1)
				putchar(' ');
			flags = 0;
		} else {
			putchar(c);
			flags = 1;
		}
	}
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-10.c
 *
 *    Description:  制表符替换为\t,回退符替换为\b,反斜杠替换为\\
 *
 *        Version:  1.0
 *        Created:  2010年12月29日 13时33分13秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

#define ESC_CHAR '\\'

int main(void)
{
	int c;

	while ((c = getchar()) != EOF) {
		switch (c) {
		case '\b':
			putchar(ESC_CHAR);
			putchar('b');
			break;
		case '\t':
			putchar(ESC_CHAR);
			putchar('t');
			break;
		case ESC_CHAR:
			putchar(ESC_CHAR);
			putchar(ESC_CHAR);
			break;
		default:
			putchar(c);
			break;
		}
	}
	return 0;
}

1-11不懂

/*
 * ==========================================================================
 *
 *       Filename:  1-12.c
 *
 *    Description:  编写一个程序,以每行一个单词的形式打印其输入
 *
 *        Version:  1.0
 *        Created:  2010年12月29日 13时44分29秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

int main(void)
{
	int c;
	int flags = 1;
	while ((c = getchar()) != EOF) {
		if (c == ' ' || c == '\n' || c == '\t') {
			if (flags)
				putchar('\n');
			flags = 0;
		} else {
			putchar(c);
			flags = 1;
		}

	}
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-13.c
 *
 *    Description:  编写一个程序,打印输入中单词长度的直方图
 *
 *        Version:  1.0
 *        Created:  2010年12月31日 21时28分46秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

int isspace2(int c)
{
	if (c == ' ' || c == '\n' || c == '\t')
		return 1;
	else
		return 0;
}

int main(void)
{
	int c;

	while ((c = getchar()) != EOF)
		if (!isspace2(c))
			putchar('*');
		else
			putchar('\n');

	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-13.c
 *
 *    Description:  编写一个程序,打印输入中单词长度的直方图(垂直直方图)
 *
 *        Version:  1.0
 *        Created:  2010年12月31日 21时28分46秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>
#include <ctype.h>
#define MAXWORDS 20 //单词最大数量

int main(void)
{
	int c, j, maxlen = 0, i = 0, n = 0;  //maxlen为最长长度, i为数组长度,n为单个单词长度
	int a[MAXWORDS];

	while ((c = getchar()) != EOF)
		if (!isspace(c))
			++n;
		else {
			if (maxlen < n)
				maxlen = n;
			a[i++] = n;
			n = 0;
		}

	while (maxlen--) {
		for (j = 0; j < i; ++j)
			if ((a[j])-- > 0)
				putchar('*');
			else
				putchar(' ');
		putchar('\n');
	}

	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-14.c
 *
 *    Description:  打印输入中各个字符出现频度的直方图
 *
 *        Version:  1.0
 *        Created:  2010年12月31日 23时42分44秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

int main(void)
{
	int c, i = 0;
	int a[95];		//除去不可显示字符1-31,127
	for (i = 0; i < 95; ++i)
		a[i] = 0;

	while ((c = getchar()) != EOF)
		if ((c = getchar()) > 31 && (c = getchar()) < 127)
			++a[c - 32];
	for (i = 0; i < 95; ++i) {
		printf("%-5c", i + 32);
		while (a[i] > 0) {
			putchar('*');
			--a[i];
		}
		printf("\n");

	}
	return 0;
}
#include <stdio.h>

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

int main(void)
{
	int c, i, j = 0, sptabnum = 0, tabnum = 0;	//sptabnum记录空格或Tab数目,tabnum记录空格数目
	char line[MAXLINE];

	for (i = 0; i < MAXLINE && (c = getchar()) != EOF; ++i) {
		line[j++] = c;
		if (c == '\n') {
			j = j - sptabnum - 1;
			line[j] = '\0';   //删除每个输入行末尾的空格及制表符
			if ((j + tabnum) > 0)	//如果输入行不完全是空格或者非空
				printf("%s\n", line);
			j = sptabnum = tabnum = 0;
		} else if (c == '\t') {
			++tabnum;
			++sptabnum;
		} else if (c == ' ')
			++sptabnum;
		else {
			sptabnum = 0;
			tabnum = 0;
		}
	}

/*如果输入字符为EOF,显示之前输入的行内容 */
	if (c == EOF) {
		line[j] = '\0';
		printf("\n%s", line);
	}

	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-19.c
 *
 *    Description:  reverse(s)
 *
 *        Version:  1.0
 *        Created:  2011年01月01日 13时08分11秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

void reverse(char s[])
{
	int j, temp, i;
	i = j = 0;
	while (s[i++]) ;	//结果i为字符串S长度,包括\0

	i = i - 2;		//此时i为字符串s中最后一个字符下标
	while (j < i) {
		temp = s[j];
		s[j++] = s[i];
		s[i--] = temp;
	}
}

int main(void)
{
	char s[] = "wo ai ni,lao po";
	reverse(s);
	printf("%s\n", s);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-20.c
 *
 *    Description:
 *    将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方。
 *
 *        Version:  1.0
 *        Created:  2011年01月01日 16时52分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

void detab(void)
{
	int tabnum = 0, c;

	while ((c = getchar()) != EOF) {
		if (c == '\t') {
			++tabnum;
			printf("        ");	//tabsize为8个字符
		} else if (tabnum == 0)
			putchar(c);
		else if (tabnum > 0)
			putchar(' ');
		if (tabnum == 2)
			tabnum = 0;
	}
}

int main(void)
{
	detab();
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  1-21.c
 *
 *    Description:  编写程序entab,
 *    将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变。
 *
 *        Version:  1.0
 *        Created:  2011年01月01日 22时03分56秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>
#include <string.h>

#define TABSIZE 4

void entab(char s[])
{
	int i, j, k = 0, spnum = 0;

	for (i = 0; i < strlen(s); ++i, ++k)
		if (s[i] == ' ')
			++spnum;
		else {
			k -= spnum;
			for (j = spnum / TABSIZE; j > 0; --j) {
				s[k++] = '\t';
			}
			for (j = spnum % TABSIZE; j > 0; --j) {
				s[k++] = ' ';
			}
			s[k] = s[i];
			spnum = 0;
		}
	s[k] = '\0';
}

int main(void)
{
	char a[] = "wo        ai ni";
	printf("%d\n", strlen(a));

	entab(a);
	printf("%s\n", a);
	printf("%d\n", strlen(a));
	return 0;
}
未完成
未完成
未完成
/*
 * ==========================================================================
 *
 *       Filename:  2-3.c
 *
 *    Description:
 *    编写函数htoi(s),把十六进制数字组成的字符串(包括可选的前缀0X或0x)转换为与之等价的整形值。
 *
 *        Version:  1.0
 *        Created:  2011年01月01日 22时23分58秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

int htoi(char hexstr[])
{
	int i = 0, tmp, result = 0, hexg = 0;
	if (hexstr[i] == '0' && (hexstr[i + 1] == 'x' || hexstr[i + 1] == 'X'))
		i = 2;
	while (hexstr[i]) {
		tmp = hexstr[i];
		if (tmp >= '0' && tmp <= '9')
			hexg = tmp - '0';
		else if (tmp >= 'a' && tmp <= 'f')
			hexg = tmp - 'a' + 10;
		else if (tmp >= 'A' && tmp <= 'F')
			hexg = tmp - 'A' + 10;
		else {
			printf("Your input is error\n");
			result = 0;
			break;
		}
		result = result * 16 + hexg;
		i++;
	}
	return result;
}

int main(void)
{
	char a[] = "0xF56";
	printf("%d\n", htoi(a));
	return 0;

}
/*
 * ==========================================================================
 *
 *       Filename:  2-4.c
 *
 *    Description:
 *    编写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 10时01分49秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

#include <stdio.h>

void squeeze(char s1[], char s2[])
{
	int i, j, k, eqnum = 0;

	for (i = k = 0; s1[i] != '\0'; i++) {
		for (j = 0; s2[j] != '\0'; j++)
			if (s1[i] == s2[j])
				++eqnum;
		if (eqnum == 0)
			s1[k++] = s1[i];
		eqnum = 0;
	}
	s1[k] = '\0';
}

int main(void)
{
	char a[] = "sunbin";
	char b[] = "hankangli";
	squeeze(a, b);

	printf("%s\n", a);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  2-5.c
 *
 *    Description: 编写函数any(s1,s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 10时14分54秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

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

int any(char s1[], char s2[])
{
	int i, j;

	for (i = 0; s1[i] != '\0'; ++i)
		for (j = 0; s2[j] != '\0'; ++j) {
			if (s1[i] == s2[j])
				return j;
		}

	return -1;
}

int main(void)
{
	char a[] = "shit";
	char b[] = "fucking";

	printf("%d\n", any(a, b));
	printf("%c\n", *strpbrk(a, b));
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  2-6.c
 *
 *    Description:  编写一个函数setbits(x,p,n,y),该函数返回对x执行下列操作后
 *			的结果值:将x从第p位开始的n个二进制位设置为y中最右边n
 *			位的值,x的其余各位保持不变
 *        Version:  1.0
 *        Created:  2011年01月02日 10时45分20秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

int setbits(int x, int p, int n, int y)
{
	return (x >> (p - n + 1) & ~(~0 << n)) | (y >> n << n);
}

int main(void)
{
	int a = 89;
	int b = 89;
	printf("%d\n", setbits(a, 4, 3, b));
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  2-7.c
 *
 *    Description:  编写一个函数invert(x,p,n),该函数返回对x执行下列操作后的
 *	      结果值:将x中从第p位开始的n个二进制位求反,x的其余各位保持不变
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 11时08分11秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

int invert(unsigned int x, int p, int n)
{
	return x ^ ((~0 >> (p + 1 - n)) & ~(~0 << n) << (p + 1 - n));
}

int main(void)
{
	printf("%d", invert(156, 4, 3));
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  2-8.c
 *
 *    Description:
 *    编写一个函数rightrot(x,n),该函数返回将x循环右移(即从最右端移出的位将从最左端移入)n位后所得到的值
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 14时40分38秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>
#include <limits.h>

int rightrot(unsigned int x, int n)
{
	int y;			//y为x所移出N位的值
	y = x & ~(~0 << n);

	return x >> n | (y << (sizeof(x) * CHAR_MAX - n));
}

int main(void)
{
	printf("%d\n", rightrot(51, 2));
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  2-9.c
 *
 *    Description:  重写bitcount函数
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 17时59分43秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

int bitcount(unsigned x)
{
	int b;
	for (b = 0; x != 0; x &= (x - 1))
		b++;
	return b;
}

int main(void)
{
	printf("%d\n", bitcount(50));
	return 0;
}
int binsearch2(int x, int v[], int n)
{
	int low, high, mid;

	low = 0;
	high = n - 1;
	mid = (low + high) / 2;
	while (low <= high && x != v[mid]) {
		if (x < v[mid])
			high = mid - 1;
		else
			low = mid + 1;
		mid = (low + high) / 2;
	}
	if (x == v[mid])
		return mid;
	else
		return -1;
}
/*
 * ==========================================================================
 *
 *       Filename:  3-2.c
 *
 *    Description:  编写一个函数escape(s,t),
 *    将字符串t复制到字符串s中,并在复制过程中将换行符、指标符等不可见字符分别转换为\n、\t等相应的可见的转移字符序列
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 18时51分17秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>
#include <string.h>

void escape(char s[], char t[])
{
	int i = 0, j = 0;
	while (t[i] != EOF) {
		switch (t[i]) {
		case '\n':
			s[j++] = '\\';
			s[j++] = 'n';
			break;
		case '\t':
			s[j++] = '\\';
			s[j++] = 't';
			break;
		default:
			s[j++] = t[i];
			break;
		}
		++i;
	}
	s[j] = EOF;
}

int main(void)
{
	char s[50];
	char t[20] = "wo ai			\n\n haha";
	escape(s, t);
	printf("%s\n", s);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  3-2.c
 *
 *    Description:  编写一个函数escape(s,t),
 *    将字符串t复制到字符串s中,并在复制过程中将换行符、指标符等不可见字符分别转换为\n、\t等相应的可见的转移字符序列
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 18时51分17秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */
#include <stdio.h>

void escape2(char s[], char t[])
{
	int i = 0, j = 0, k = 0;
	while (t[i] != EOF) {
		switch (t[i]) {
		case '\\':
			++k;
			break;
		case 't':
			if (k == 1)
				s[j++] = '\t';
			k = 0;
			break;
		case 'n':
			if (k == 1)
				s[j++] = '\n';
			k = 0;
			break;
		default:
			for (; k > 0; --k)
				s[j++] = '\\';
			s[j++] = t[i];
			k = 0;
			break;
		}
		++i;
	}
	s[j] = EOF;
}

int main(void)
{
	char s[50];
	char t[30] = "lao \\t po\\n \\t \\t ha \\n haha";
	escape2(s, t);
	printf("%s\n", s);
	return 0;
}
/*
 * ==========================================================================
 *
 *       Filename:  3-3.c
 *
 *    Description:
 *    编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中扩展为等价的完整列表abc..xyz.该函数可以处理大小写字符和数字,并可以处理a-b-c,a-z,0-9与a-z等类似的情况。作为前导和未遂的-字符原样排印。
 *
 *        Version:  1.0
 *        Created:  2011年01月02日 20时52分01秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  SD44 (), sd44sd44@yeah.net
 *        Company:  http://sd44.is-programmer.com/
 *
 * ==========================================================================
 */

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

void expand(char s1[], char s2[])
{
	int i, j, k, stag;
	i = j = 0;

	for (i = 0; s1[i] != '\0'; i++) {

		if (s1[i] == '-' && islower(s1[i - 1]) && islower(s1[i + 1])
		    && ((s1[i + 1] - s1[i - 1]) > 0)) {
			stag = s1[i - 1];
			k = s1[i + 1] - s1[i - 1] - 1;
			while (k--)
				s2[j++] = ++stag;
		} else if (s1[i] == '-' && isupper(s1[i - 1])
			   && isupper(s1[i + 1])
			   && ((s1[i + 1] - s1[i - 1]) > 0)) {
			stag = s1[i - 1];
			k = s1[i + 1] - s1[i - 1] - 1;
			while (k--)
				s2[j++] = ++stag;
		} else
		    if (s1[i] == '-' && isdigit(s1[i - 1]) && isdigit(s1[i + 1])
			&& ((s1[i + 1] - s1[i - 1]) > 0)) {
			stag = s1[i - 1];
			k = s1[i + 1] - s1[i - 1] - 1;
			while (k--)
				s2[j++] = ++stag;
		} else
			s2[j++] = s1[i];
	}
	s2[j] = '\0';
}

int main(void)
{
	char a[] = "h-a-hazz 3-9-5  3-A- ";
	char b[100];
	expand(a, b);

	printf("%s\n", b);
	return 0; 
}
/*
 * =====================================================================================
 *
 *       Filename:  3-4.c
 *
 *    Description:
 *    修改itoa函数,使其能够处理最大的负数,即n等于-2(n-1次方)的情况
 *
 *        Version:  1.0
 *        Created:  2011年01月08日 15时30分35秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Sd44 (), sd44sd44@yeah.net
 *       Homepage:  http://sd44.is-programmer.com
 *
 * =====================================================================================
 */

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

void reverse(char a[])
{
	int c, i, j;
	for (i = 0, j = strlen(a) - 1; i < j; i++, j--) {
		c = a[i];
		a[i] = a[j];
		a[j] = c;
	}
}

void itoa(int n, char s[])
{
	int i, sign;
	sign = n;

	i = 0;
	do {
		s[i++] = abs(n % 10) + '0';
	} while (n /= 10);

	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';
	reverse(s);
}

int main(void)
{
	char b[50];
	itoa(-2147483647, b);
	printf("%s\n", b);
	return 0;
}

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

void reverse(char a[])
{
	int c, i, j;
	for (i = 0, j = strlen(a) - 1; i < j; i++, j--) {
		c = a[i];
		a[i] = a[j];
		a[j] = c;
	}
}

void itoa(int n, char s[])
{
	int i, sign;
	sign = n;

	i = 0;
	do {
		s[i++] = abs(n % 10) + '0';
	} while (n /= 10);

	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';
	reverse(s);
}

int main(void)
{
	char b[50];
	itoa(-2147483647, b);
	printf("%s\n", b);
	return 0;
}

 

/*
 * =====================================================================================
 *
 *       Filename:  3-6.c
 *
 *    Description:
 *    itoa函数,使得该函数可以接收三个参数,其中,第三个参数为最小字段宽度。
 *
 *        Version:  1.0
 *        Created:  2011年01月08日 15时55分08秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Sd44 (), sd44sd44@yeah.net
 *       Homepage:  http://sd44.is-programmer.com
 *
 * =====================================================================================
 */
#include    <stdio.h>
#include    <string.h>

void reverse(char a[])
{
	int c, i, j;

	for (i = 0, j = strlen(a) - 1; i < j; i++, j--) {
		c = a[i];
		a[i] = a[j];
		a[j] = c;
	}
}

void itoa(int n, char s[], int width)
{
	int i, sign, temp = n, widnum = 0;
	if ((sign = n) < 0)
		n = -n;

	i = 0;
	do {
		s[i++] = n % 10 + '0';
		++widnum;	// widnum为整数n的位数
	} while (n /= 10);

	if (sign < 0) {
		s[i++] = '-';
//      如果n为负数,则宽度+1
		++widnum;
	}

	for (temp = width - widnum; temp > 0; --temp)
		s[i++] = ' ';

	s[i] = '\0';
	reverse(s);
}

int main(void)
{
	char b[50];
	itoa(-100, b, 8);
	printf("%s\n", b);
	return 0;
}

 

求2的N次方(要求,最简算法复杂度为lgn)

 

/*
 * =========================================================================
 *
 *       Filename:  mypow.c
 *
 *    Description:  编写一个函数double mypow(double x, int n);
 *    求x的n次方,参数n是正整数。算法复杂度考虑lgn。  !!递归版
 *
 *        Created:  2010年12月05日 17时20分36秒
 *       Compiler:  gcc
 * ==========================================================================
 */
#include <stdio.h>

double mypow(double x, int n)
{
	if (n == 0)
		return 1;
	if (n == 1)
		return x;
	if (n % 2 != 0)
		return x * mypow(x, n - 1);
	else
		return mypow(x*x, n / 2);
}

int main(void)
{
	printf("%f\n", mypow(2, 11));
	return 0;
}
#include	<math.h>
#include	<stdio.h>
#include    <stdio.h>
#include    <math.h>

double mypow(double x, int n)
{
	double result = 1.0;
	if (n == 0)
		return 1;
	while (n) {
		if (n & 1)
			result *= x;
		x *= x;
		n >>= 1;
	}
	return result;
}

int main(void)
{
	for (int i = 0; i < 16; i++)
		printf("%-2d: mypow: %-10.0f \t pow:%-10.0f\n", i,
		       mypow(2, i), pow(2, i));
	return 0;
}

 

折半算法

 

/*
 *       Filename:  binary.c
 *    Description: 从一组排序好的序列里找出某个元素的位置(折半查找) 
 * ==========================================================================
 */
#include <stdio.h>
#define LEN 8

int a[LEN] = { 1, 2, 2, 5, 5, 6, 8, 9 };

int binary(int number)
{
	int mid, start = 0, end = LEN - 1;

	while (start <= end) {
		mid = (start + end) / 2;
		if (a[mid] < number)
			start = mid + 1;
		else if (a[mid] > number)
			end = mid - 1;
		else {
			while (a[mid] == number) {
				--mid;
			};	//返回最早出现的匹配位值
			return mid + 1;
		}
	}
	return -1;
}

int main(void)
{
	printf("%d\n", binary(2));
	return 0;
}

 

合理的有理数实现 代码

 

/*
 * ==========================================================================
 *
 *       Filename:  prac.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2010年10月20日 16时50分14秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 ==========================================================================
 */
#include <stdio.h>
#include <math.h>

int euclid(int a, int b)
{
    if (a % b == 0)
        return abs(b);
    else
        return euclid(b, a % b);
}

struct rational {
    int x,y
} ;

struct rational add_rational (struct rational z1,struct rational z2)
{
    struct rational z;
    z.x = z1.x + z2.x;
    z.y = z1.y + z2.y;
    return z;
}
struct rational sub_rational (struct rational z1,struct rational z2)
{
    struct rational z;
    z.x = z1.x - z2.x;
    z.y = z1.y - z2.y;
    return z;
}
struct rational mul_rational (struct rational z1, struct rational z2)
{
    struct rational z;
    z.x = z1.x * z2.x;
    z.y = z1.y * z2.y;
    return z;
}
struct rational div_rational (struct rational z1, struct rational z2)
{
    struct rational z;
    z.x = z1.x / z2.x ;
    z.y = z1.y / z2.y ;
    return z;
}

struct rational make_rational (int a,int b)
{
    struct rational z;
    z.x = a;
    z.y = b;
    return z;
}

int print_rational (struct rational z)
{
    if (z.y < 0) {
        z.x = -z.x;
        z.y = -z.y;
    }
    if (z.y == 0)
        printf ("0 不能做除数\n");
    else if (z.x % z.y == 0) //如果能被整除,则变为最简分数
        printf ("%d\n", z.x/z.y);
    else
    {
        int gcd= euclid( z.x,z.y);
        z.x = z.x/gcd;
        z.y = z.y/gcd;
        printf ("%d/%d\n", z.x, z.y);
    }
    return 0;
}

int main(void)
{
    struct rational a = make_rational(1, 8); 
    struct rational b = make_rational(-1, 8); 
    print_rational(add_rational(a, b));
    print_rational(sub_rational(a, b));
    print_rational(mul_rational(a, b));
    print_rational(div_rational(a, b));
    return 0;
}

最大公约数与Fibnacci的递归和循环实现

最大公约数与Fibnacci数列的解答。(递归法和循环法)

阅读全文