代码改变世界

Pointers and Arrays_2

2017-02-09 18:08  星星之火✨🔥  阅读(272)  评论(0)    收藏  举报

1、用指针方式实现strcat 函数:strcat(s, t) 将t 指向的字符串复制到s 指向的字符串的尾部。

// strcat: concatenate t to the end of s; pointer version
void strcat(char *s, char *t)
{
	while(*s)
		s++;
	while(*s++ = *t++)
		;
}

2、编写函数strend(s, t)。如果字符串t 出现在字符串s 的尾部,该函数返回1;否则返回0。

// strend: return 1 if string t occurs at the end of s
int strend(char *s, char *t)
{
	char *bs = s; // remember beginning of strs
	char *bt = t;
	
	for(; *s; s++) // end of the string s
		;
	for(; *t; t++) // end of the string t
		;
	for(; *s == *t; s--, t--)
		if(t == bt || s == bs)
			break; // at the beginning of a str
	if(*s == *t && t == bt && *s != '\0')
		return 1;
	else
		return 0;
			
}

注意,这个函数可以有效处理边界情况:两个字符串皆为空,任意一个为空而另一个不空。

3、实现库函数strncpy、strncat 和strncmp 它们最多对参数字符串中的前n 个字符进行操作。例如,函数strncpy(s, t, n) 将t 中最多前n 个字符复制到s 中

// strncpy: copy n characters from t to s
void strncpy(char *s, char *t, int n)
{
	while(*t && n-- > 0)
		*s++ = *t++;
	while(n-- > 0)
		*s++ = '\0';
}

// strcat: concatenate n characters of t to the end of s
void strncat(char *s, char *t, int n)
{
	void strncpy(char *s, char *t, int n);
	int strlen(char *);
	
	strncpy(s+strlen(s), t, n);
}

// strncmp: compare at most(不超过、至多.所以下面是--n 而不是n--) n characters of t with s
int strncmp(char *s, char *t, int n)
{
	for( ; *s == *t; s++, t++)
		if(*s == '\0' || --n < 0)
			return 0;
	return *s - *t;
}

注意:这里为了方便起见,strncpy 和strncat 的返回类型都是void,而其对应的库函数的版本返回的都是一个指向结果字符串开头的指针。应该是为了进行链式编程吧。

strncpy 最多从字符串t 赋值n 个字符到字符串s,如果字符少于n 个,将在字符串s 的末尾填充字符'\0'。

4、采用指针而非数组索引方式改写之前的程序,如:getline、atoi 及其变体、reverse、strindex、getop 等等。

指针方式实现getline:

#include <stdio.h>

// getline: read a line into s, return length
int getline(char *s, int lim)
{
	int c;
	char *t = s;
	
	while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
		*s++ = c;
	if(c == '\n')
		*s++ = c;
	*s = '\0';
	return s - t;
}

指针方式实现atoi

#include <ctype.h>

// atoi: convert s to integer; pointer version
int atoi(char *s)
{
	int n, sign;
	
	for(; isspace(*s); s++) // skip white space
		;
	sign = (*s == '-') ? -1 : 1;
	if(*s == '+' || *s == '-') // skip sign
		s++;
	for(n = 0; isdigit(*s); s++)
		n = 10 * n + *s - '0';
		
	return sign * n;
}

指针方式实现itoa,reverse:

void reverse(char *);

// itoa: convert n to characters in s; pointer version
void itoa(int n, char *s)
{
	int sign;
	char *t = s; // save pointer to s
	
	if((sign = n) < 0) // record sign
		n = -n; // make n positive
	do // generate digits in reverse order
	{
		*s++ = n % 10 + '0'; // get next digit
	}while((n /= 10) > 0); // delete it
	if(sign < 0)
		*s++ = '-';
	*s = '\0';
	reverse(t);
}

#include <string.h>

// reverse: reverse string s in place
void reverse(char *s)
{
	int c;
	char *t;
	
	for(t = s + strlen(s) - 1; s < t; s++, t--)
	{
		c = *s;
		*s = *t;
		*t = c;
	}
}

指针方式实现strindex: 

// strindex: return index of t in s, -1 if none
int strindex(char *s, char *t)
{
	char *b = s; // beginning of string s
	char *p, *r;
	
	for( ; *s != '\0'; s++)
	{
		for(p=s, r=t; *r != '\0' && *p == *r; p++, r++)
			;
		if(r > t && *r == '\0')
			return s - b;
	}
	return -1;
}

指针方式实现atof

#include <ctype.h>

// atof: convert string s to double; pointer version
double atof(char *s)
{
	double val, power;
	int sign;
	
	for( ; isspace(*s); s++) // skip white space
		;
	sign = (*s == '-') ? -1: 1;
	if(*s == '+' || *s == '-')
		s++;
	for(val = 0.0; isdigit(*s); s++)
		val = 10.0 * val + (*s - '0');
	if(*s == '.')
		s++;
	for(power = 1.0; isdigit(*s); s++)
	{
		val = 10.0 * val + (*s - '0');
		power *= 10.0;
	} 
	return sign * val / power;
}

指针方式实现getop 函数:

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

#define NUMBER '0' //signal that a number was found

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

// getop: get next operator or numeric operand; pointer version
int getop(char *s)
{
	int c;
	
	while((*s = c = getch()) == ' ' || c == '\t')
		;
	*(s+1) = '\0';
	if(!isdigit(c) && c != '.')
		return c; // not a number
	if(isdigit(c)) // collect integer part
		while(isdigit(*++s = c = getch()))
			;
	if(c == '.') // collect fraction part
		while(isdigit(*++s = c = getch()))
			;
	*s = '\0';
	if(c != EOF)
		ungetch(c);
	return NUMBER;
}