鸟语天空
函数和指针
post by:追风剑情 2020-3-16 14:43

示例

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> //C99特性
#include <string.h>
#include <math.h>
#include <ctype.h>

//函数指针指向函数代码起始处的内存地址
//要注意运算符*的优先级
//void (*pf)(char *); //pf是一个指向函数的指针
//void *pf(char *);   //pf是一个返回字符指针的函数
/*
提示:
要声明一个指向特定类型函数的指针,可以先声明一个该类型的函数,然后把函数名替换成(*pf)
形式的表达式。然后,pf就成为指向该类型函数的指针。
*/

#define LEN 81
char* s_gets(char *st, int n);
char showmenu(void);
void eatline(void); // 读取至行末尾
void show(void(*fp)(char *), char * str);
void ToUpper(char *); // 把字符串转换为大写
void ToLower(char *); // 把字符串转换为小写
void Transpose(char *); // 大小写转置
void Dummy(char *); // 不更改字符串

//typedef void (*V_FP_CHARP) (char *);

int main(int argc, char* argv[])
{
	char line[LEN];
	char copy[LEN];
	char choice;
	// 声明一个函数指针,被指向的函数接受char *类型的参数,无返回值
	void (*pfun) (char *);
	//或者这样声明
	//V_FP_CHARP pfun;
	pfun = Dummy;

	puts("Enter a string (empty line to quit):");
	while (s_gets(line, LEN) != NULL && line[0] != '\0')
	{
		while ((choice = showmenu()) != 'n')
		{
			switch (choice)
			{
			//函数名代表函数的地址
			//注意:只能把类型匹配的函数地址赋给pfun
			case 'u': pfun = ToUpper; break;
			case 'l': pfun = ToLower; break;
			case 't': pfun = Transpose; break;
			case 'o': pfun = Dummy; break;
			}
			strcpy(copy, line); // 为show()函数拷贝一份
			show(pfun, copy); // 根据用户的选择,使用选定的函数
		}
		puts("Enter a string (empty line to quit):");
	}
	puts("Bye!");

	system("pause");
	return 0;
}

char showmenu(void)
{
	char ans;
	puts("Enter menu choice:");
	puts("u) uppercase       l) lowercase");
	puts("t) transposed case o) original case");
	puts("n) next string");
	ans = getchar();  // 获取用户输入
	ans = tolower(ans); // 转换为小写
	eatline(); //清理输入
	//判断输入的字符是否包含在ulton字符串中
	while (strchr("ulton", ans) == NULL)
	{
		puts("Please enter a u, l, t, o, or n:");
		ans = tolower(getchar());
		eatline();
	}
	return ans;
}

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

void ToUpper(char* str)
{
	while (*str)
	{
		*str = toupper(*str);
		str++;
	}
}

void ToLower(char* str)
{
	while (*str)
	{
		*str = tolower(*str);
		str++;
	}
}

void Transpose(char* str)
{
	while (*str)
	{
		if (islower(*str))
			*str = toupper(*str);
		else if (isupper(*str))
			*str = tolower(*str);
		str++;
	}
}

void Dummy(char* str)
{
	// 不改变字符串
}

//void show(V_FP_CHARP fp, char *)
void show(void(*fp)(char*), char* str)
{
	//由于历史原因ANSI C认为下面两种函数调用方式等价
	(*fp)(str); // 把用户选定的函数作用于str
	//fp(str);  //与(*fp)(str)写法等效
	puts(str);  // 显示结果
}

// 自己实现读取函数
char* s_gets(char* st, int n)
{
	char* ret_val;
	int i = 0;
	ret_val = fgets(st, n, stdin);
	if (ret_val) //即,ret_val != NULL
	{
		while (st[i] != '\n' && st[i] != '\0')
			i++;
		if (st[i] == '\n')
			st[i] = '\0';
		else
			while (getchar() != '\n')
				continue;
	}
	return ret_val;
}

运行测试

1111.png

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容