版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章第七章 字符数组与字符串字符数组与字符串4本章主要内容123字符型数据字符数组与字符串常用字符串函数常用字符串函数字符串应用举例字符串应用举例5字符串数组字符串数组7.1 字符型数据n7.1.1 字符型数据的存储n7.1.2 转义序列n7.1.3 字符型数据的输入输出7.1.1 字符数据的存储n字符型数据的存储方法根据计算机的不同而不同,因为不同机器可能有不同的字符集。当今最常用的字符集是ASCII(美国信息交换标准码)字符集,它用7个二进制位表示128个字符。在ASCII码中,数字0-9用01100000111001码来表示,字母A-Z用10000011011010表示。值值符号符号值
2、值符号符号值值符号符号0空字符44,9132空格45-9233!46.933447/9435#48 570 995-36$58:9637%59;97 122a z38&6012541)63?12642*64127DEL43+65 90A Z字符数据类型占 8 位内存signed或 unsignedSigned-128 至 +127 unsigned 0 至 255 在C语言中,字符和整数之间存在着密切的关系。C语言把字符当成小整数进行处理。字符型溢出问题n输入一个英文小写字符和正整数k(k26),将英文字母加密并输出。n加密思想:将每个字母c加一个序数k,即用它后面的第k个字母代替,变
3、换公式:c=c+k。如果字母为z,则后一个字母是a,也就是字母表形成一个圆。解决问题: 字符加密#includeint main()char ch;int k;scanf(%c %d, &ch, &k);ch = ch + k; /可能类型溢出 if(ch z)ch = ch - 26;printf(%cn, ch);return 0;源程序7-1:char类型溢出输入小于g的字符和任意k(1-25),运行结果正确当输入z 6 或 g 25 , 结果错误原因是char类型溢出signed char: -128 至 +127z+6的值是的值是128超出超出char表表示范围示范围
4、#includeint main()unsigned char ch;int k;scanf(%c %d, &ch, &k);ch = ch + k; if(ch z)ch = ch - 26;printf(%cn, ch);return 0;解决方法1:使用unsigned charunsigned char: 0 至 255一个英文小写字符和正整数k(k26)的和,不会超出这个范围#includeint main()char ch;int k;scanf(%c %d, &ch, &k); if(ch + k z) ch = ch + k - 26; else
5、 ch = ch + k;printf(%cn, ch);return 0;解决方法2:分类处理,避免溢出若ch + k z,则减去26后存储,避免存储时溢出在计算ch + k 的过程中不会溢出,因为因为编译器把算术运算中涉及的char类型都提升为int类型#includeint main()int k = 123456 * 123456 / 123456; printf(%dn, k); return 0;注意计算过程中的溢出 其实有更多的类型溢出是发生在计算阶段,例如表达式:k = 123456 * 123456 / 123456, 虽然结果不会超出int范围,但在计算过程中,中间结果超出
6、int范围,也将发生溢出。该程序无法得到正确结果,是因为计算 123456 * 123456的结果超出了int类型的表示范围。避免此类问题的方法:1、选择表示范围更大的数据类型2、先除后乘,但要解决好整数除法带来的问题。希望输出:Jack: Youre my best friend代码:printf(Jack: Youre my best friendn);输出单引号用,输出双引号用 。C语言提供了转义序列来表示特殊字符,有字符转义序列和数字转义序列7.1.2 转义序列如何输出双引号和单引号?字符 转义序列转义序列转义序列名称名称描述描述a 警告产生一则警告。b 退格将光标回退一格。f 换页将
7、光标移到下一页的第一格。n 换行将光标移到下一行的第一格。r 回车将光标移到当前行的第一格。t 水平制表 将光标移到下一个水平制表位置。v 垂直制表将光标移到下一个垂直制表位置。 单引号产生一个单引号。 双引号产生一个双引号。? 问号产生一个问号。反斜线产生一条反斜线。0 空产生一个空字符。 字符转义序列使用起来很容易,但数量有限,并没有包含所有无法打印的ASCII字符。C语言提供了数字转义序列。所有ASCII码字符,都可以用数字转义序列来表示。可以用八进制数或十六进制来书写转义字符。n八进制转义序列:由和跟随其后的最多含有三位数字的八进制数组成。例如,a的ASCII码对应的八进制是141,则
8、数字转义序列141就表示a。n十六进制转义序列:由x和跟随其后的十六进制数组成。例如,a的ASCII码对应的十六进制是61,则数字转义序列x61就表示a。数字 转义序列数字转义序列(部分)八进制转义序列八进制转义序列十六进制转义序列十六进制转义序列描述描述7 x7响铃10 x8退格键12 x0C换页键10 x0A换行键40 x20空格60 x300101x41A141x61aprintf(“a10bn”); /输出输出: b, 因为转义序列因为转义序列10是是 退格键退格键printf(“14110142n”); /输出输出: b, 含义同上含义同上7.1.3 字符数据的输入输出nscanf(
9、)函数和getchar()都可以用来读入单个字符。但与整型和实型数据的读入不同的是,所有输入都是合法的字符输入,包括空格、回车等空白符。若有以下输入语句:scanf(%c%c%c, &ch1, &ch2, &ch3); 如果输入为:a b c结果是:ch1值为a,ch2值为 ,ch3值为b。 如何跳过空白符 如果在程序中需要先读入一个整数存入变量n, 然后读入一个字符存入变量ch,输入格式如下:5M该如何用scanf()函数实现呢?若写为: scanf(%d, &n); scanf(%c, &ch);存入ch中的将是数字5之后的回车符。解决方法解决方法解
10、决方法1:加一个读入语句将数组5之后的回车处理掉: scanf(%d, &n); getchar(); /* 将缓冲区中的回车读入*/ scanf(%c, &ch);解决方法解决方法2:为了强制scanf()函数在读入字符前跳过空白符,需要在格式串中的%c之前加上一个空格: scanf(%d, &n); scanf( %c, &ch);scanf格式串中的空白意味着“跳过零个或多个空白字符”。7.1.4 字符处理函数前面已经讲过如何把小写字母转换成大写字母:if(ch = a & ch = z) ch = ch - 32;其实可以使用库函数toupper
11、()来完成上述操作,即ch = toupper(ch);toupper(ch)函数会检测参数ch是否是小写字母,如果是,它会把ch转换成大写字母返回,否则原样返回参数的值。tolower(ch)会把ch转换成小写字母返回isdigit(ch)用来判断一个字符ch是否是数字isalpha(ch)用来判断一个字符是否是字母,重写程序4-13:字符分类统计letter = digit = other = 0;while(ch = getchar(), ch != n) if( isalpha(ch) ) /*若ch是字母*/ letter+; else if( isdigit(ch) ) /*若ch
12、是数字*/ digit+; else /*其他字符*/ other+;ctype.h头文件中的部分函数函数功能功能tolower()转换为小写字母toupper()转换为大写字母islower()判断是否是小写字母isupper()判断是否是大写字母isalpha()判断是否是小写或大写字母isdigit()判断是否是十进制数字(0-9)isxdigit()判断是否是十六进制数字(0-9,a-f,A-F)isblank()判断是否是空白字符(空格,t)7.2 字符数组与字符串char a = W;char b = a;char c = n;char d = g;char e = L;char
13、f = i;如何让程序存储我的姓名?WangLichar name15 = W, a, n, g, L, i; 用若干个字符用字符数组用字符串char name15 = “Wang Li”;7.2.1统计空格解决问题:输入一行字符(字符个数不多于80),统计其中空格的个数解题思路:(1)定义字符数组 str81;(2)读入字符串若字符串确定不含空格,可以用scanf(“%s”,&str);若可能含有空格,用gets(str);(3)扫描整个字符串(不需要知道字符个数)#include int main() char str81; int i, count = 0; printf(n 请
14、输入一行字符:n ); gets(str); for(i = 0; stri != 0; i+) if(stri = ) count+; printf(n 其中的空格总数为 %d n ,count); 在循环执行时,扫描整个数组以统计出空格 的数量,直到遇到字符 0。7.2.2 一维字符数组与字符串一维字符数组的定义、引用、初始化与其他类型的一维数组一样。char str80; 定义一个含有80个字符型元素的数组str char t5 = H, a, p, p, y;初始化数组 t t0 t1 t4tHappy作为普通数组,可以用如下循环输出数组t的所有元素for(i = 0; i 5; i+
15、) putchar( ti );但是,”Happy”作为一个单词,如果能整体输入输出,显然更方便一些!字符串常量n字符串常量是双引号括起的任意字符序列HelloWorld0Hello WorldWangPingPlease enter your full name: “Hello!n字符串常量中可以包含转义序列字符串结束符字符串的字符串的有效长度有效长度:有效字符的个数:有效字符的个数字符串的存储char s80 = Happy;字符串遇 0 结束第一个 0 前面的所有字符和 0 一起构成了字符串 Happy”0 之后的其他数组元素与该字符串无关 s0 s1 s5s H a p p y 0 0
16、 0 字符串由有效字符和字符串结束符 0 组成 字符串与字符数组n在语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串n字符数组和字符串的区别是:字符串的末尾有一个空字符 0字符串可按如下方式声明并初始化:char name15 = W, a, n, g, L, i, 0;char name15 = WangLi;char password = 12345678;手工加入一个空字符系统将自动加入一个空字符省略数组大小,系统自动计算,大小为后面的字符总数加1,最后一个元素存入一个空字符。 后两种为数组赋初值的方式,本质上与第一种方式本质相同,只是写成了我们更习惯的样子。方法1:用%s
17、整体输入输出char name10;scanf(%s, name);printf(%s, name);格式描述串中使用转换字符串“%s”Wang LiWang0使用 scanf 时,不能输入空格Wang空格是%s输入结束的标志7.2.3 字符串的输入输出方法2:用gets和puts函数char name10;gets(name);puts(name);W angLi0W a n g LiWang Li从键盘上读入一个完整的行,存入字符数组name。并在最后添加字符串结束标识0把字符数组中的字符串输出到显示器。使用 gets函数允许输入空格7.3 常用字符串函数7.3.1 定义在头文件strin
18、g.h中的字符串函数(1)strlen: 求字符串长度(2)strcpy:字符串复制(赋值)(3)strcmp:字符串比较(4)strcat:字符串合并(5)strrev: 字符串逆置(1) 求字符串长度 strlen( )调用格式:调用格式:功能:功能:测试字符串长度。函数值就是测试字符串长度。函数值就是strstr中字符的中字符的个数。个数。例如:例如:char str10 = China;printf(%d, strlen(str);或或printf(%d, strlen(China);printf(%d, strlen(161bcdn);(2)字符串复制函数 strcpy( )调用格式
19、:调用格式:功能:将功能:将str2str2中的字符串复制到中的字符串复制到str1str1数组中。数组中。思考:这样赋值s1 = Beijing ; 或 s1 = s2;可以吗?为什么?s1的结果的结果例如:例如:char s110,s2 = Beijing;char s110,s2 = Beijing; strcpy(s1,s2); strcpy(s1,s2);或:或:strcpy(s1,Beijing);strcpy(s1,Beijing);字符串的赋值需要通过strcpy实现char str110 = “China”;正确char str110 ;str1 = “China”;错误改为
20、:char str110 ;strcpy(str1, “China”);char str110, str2 = “China”;str1 = str2;改为:char str110 , str2 = “China”;strcpy(str1, str2);为什么不允许这样赋值?因为数组名是一个常量,代表数组的首地址,常量不可以被赋值,其值不可改变错误对两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到0为止。如果全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准。(1返回0(2)返回一个正整数(3),返回一个负整数。 str1 s
21、tr2“cat” “fan”“Abd” “abd”“abcde” “abc”“abc” “abc”(3)字符串比较函数 strcmp( )调用格式:调用格式:比较str1和str2的大小,若前者大则返回一个正整数,若后者大则返回一个负整数,若两者相等,则返回0。=strcmp(str1, str2)0strcmp(str1, str2)0strcmp(str1, str2)=0注意: 比较两个字符串的大小只能使用此函数,而不能使用“”、“”、“=”等关系运算符。(4) 字符串连接函数 strcat( )把把str2str2中的字符串连接到中的字符串连接到str1str1字符串的后面,结果字符串
22、的后面,结果放在放在str1str1数组中数组中. .例如:例如:char str121= beijing and ;char str121= beijing and ;char str2 = shanghai;char str2 = shanghai;strcat(str1,str2);strcat(str1,str2);printf(%s,str1);printf(%s,str1);(5) 字符串逆置函数 strrev( ) 字符串字符串strstr的所有字符的顺序颠倒过来的所有字符的顺序颠倒过来( (不包括空字不包括空字符符NULL)NULL)。例如:例如:char str10=hell
23、o;char str10=hello;strrev( str );strrev( str );printf(%s,str);printf(%s,str);注意:注意:strrevstrrev()()函数不是标准函数不是标准C C的库函数,某些编的库函数,某些编译器没有包含该函数的定义,此时需要自己实现译器没有包含该函数的定义,此时需要自己实现strrevstrrev()()函数。函数。字符串逆置功能的实现str0 i数组元素数组元素 内容内容 下标下标str1 strlen-1 j void StrRev(char str) i = 0; j = len 1; while(i不相等j) str
24、i与strj互换内容 下标i从前向后依次增加 下标j从后向前依次减小 void StrRev(char str) int i, j, len; len = strlen(str); for(i = 0, j = len-1; i j; i+, j-) char temp = stri; stri = strj; strj = temp; 最大字符串n 解决问题:最大字符串。解决问题:最大字符串。n输入正整数n(0 n = 10),然后输入n个字符串,输出字典序最大的字符串。运行效果如下:请输入字符串个数:3请输入3个字符串:testcathello最大字符串: test思路:(1) 读入n(2
25、) 将max置为最小字符串(空串)。(3) 循环n次,每次读入一个字符串str,若str大于max,则将str存入max(4) 输出字符串max/* 程序7-3 */char maxN = ;scanf(%d, &n);getchar();for(i = 1; i 0 ) strcpy(max, str);puts(max);getsgets函数的读取规则函数的读取规则 只要gets遇到换行符,即便它是输入的第一个字符,gets也会停止读入并返回。如果输入的第一个字符就是换行符,则字符串将被置为空串。 所以上例中使用gets()前要清空缓冲区中的回车。方法方法1 1: getcharg
26、etchar() () getchar()读入缓冲区中剩余的回车 如上例中,用getchar()读入之前整数之后的回车。缺点是只能读入1个字符方法方法2 2:scanfscanf(“ ”) 用scanf格式串中的空白符跳过一个或多个空白符,直到遇到非空白符。方法方法3 3: fflushfflush( (stdinstdin) ) 清空输入缓冲区,通常是为了确保不影响后面的数据读取。是包含在stdio.h中的非标准库文件,不是所有编译器都支持。 课堂练习:输入n个字符串n最长字符串:输入n和n个字符串,输出其中最长的字符串。char maxN = ;scanf(%d, &n);scan
27、fscanf( );for(i=1; i strlen(max) strcpy(max, str);puts(max);scanf(%d , &n);gets函数的返回值getsgets函数的返回值:函数的返回值:1.正常读入(未遇到文件结尾)(注意,读入空串也是正常读入),则返回字符串,即返回字符串首地址,char*类型;2.遇到文件结尾,返回NULL;NULL是stdio中定义的常量0getsgets函数的危险性:函数的危险性: gets 函数没有检测缓冲区大小的问题,用户无法指定其一次最多读入多少字节的内容,所以可以随意输入很长的数组,内容可以写入内存。当年不少的黑客攻击都是利用
28、此漏洞。输入多个字符串,直到文件结束n最大字符串:输入若干个字符串,每个占一行,输出其中最大的字符串。char maxN = ;while( gets(str) ) if( strcmp(str, max) 0) strcpy(max, str);puts(max);输入多个字符串,以特殊输入结束n最大字符串:输入若干个字符串,每个占一行,若输入”#”表示输入结束。输出其中最大的字符串。char maxN = ;while( gets(str) , strcmp(str, “#”) !=0 ) if( strcmp(str, max) 0) strcpy(max, str);puts(max)
29、;7.3.2 stdlib.h中字符串转换函数(1)atof: 将一个字符串转换为一个double类型的浮点数(2)atoi:将一个字符串转换为一个int类型的整数(3)atol:将一个字符串转换为一个long int类型的整数(4)itoa: 将一个整数转换为一个字符串注意:这几个函数虽然应用广泛,但不是标准注意:这几个函数虽然应用广泛,但不是标准C C的的库函数,某些编译器没有包含该函数的定义,此时库函数,某些编译器没有包含该函数的定义,此时需要自己定义这些函数。需要自己定义这些函数。(1)字符串转换为一个浮点数 atof( )调用格式调用格式: 功能功能:将一个字符串转换为一个doubl
30、e类型的浮点数,函数值即为该浮点数 函数丢弃前面的空白字符直到遇到第一个非空白字符。从这个字符开始得到尽可能多的字符构成一个有效的浮点数,直到遇到非数字,最后一个数字后面的字符串的其他部分被忽略。printf(lfn, atof(990.0n ) );printf(lfn, atof( 990.0adfn ) );printf(lfn, atof(“a990.0n ) );(2)字符串转换为一个int数据 atoi( )调用格式调用格式: 功能功能:将一个字符串转换为一个int类型的整数,函数值即为该整数printf(lfn, atoi(990.99 ) );printf(lfn, atoi(
31、 990abcd ) );printf(lfn, atoi(a990 ) );printf(lfn, atoi( 9901234567 ) );(3)整数转换为字符串itoa( )调调用格式用格式: itoa( d, str, r);功能功能:将一个整数d,转换为r进制的数,存入字符串str,itoa(13, str, 2);puts(str);itoa(100, str, 8);puts(str);输出一个整数n和它的逆序数的和函数原型:函数原型: int InvAdd(int n); int InvAdd(int n);该函数返回该函数返回n n和和n n的逆序数的和的逆序数的和intin
32、t InvAddInvAdd( (intint n) n) char char strstrN;N; itoaitoa(n, (n, strstr, 10); , 10); /把把n n转换为字符串转换为字符串strstr strrevstrrev( ( strstr); ); /逆置逆置strstr return n + return n + atoiatoi( (strstr); ); /返回返回 n n 和逆序数的和和逆序数的和 7.3.3 stdio中字符串函数sprintf(str, %d ,n);功能是把格式化的数据写入字符串 str中。 sscanf(str, %d , &
33、;n);功能是从字符串str中进行格式读入/ /* *strstr中是中是1818位身份证,该函数输出对应生日位身份证,该函数输出对应生日* */ /intint PntBirthdayPntBirthday(char (char strstr) sscanf(str, %*6d%4d%2d%2d , &y, &m, &d); printf( %d年%d月%d日n , y, m, d); 水仙花数的判断#include int main(void)char str10;int n, a, b, c;gets(str); /* 将输入存入字符串*/sscanf(str,
34、“%d”, &n); /* 作为一个三位数读入*/sscanf(str, “%1d%1d%1d”, &a, &b, &c); /* 三个一位数*/ if(n = a*a*a + b*b*b + c*c*c) printf(yesn); else printf(non); return 0;使用sscanf(),分析各位数字,实现水仙花数的判断Super primeSuper prime是指一个k位的正整数,它的前一位,前两位,.,前k位都是素数。函数原型:函数原型: int IsSuperPrm(int n); int IsSuperPrm(int n);若若n
35、 n是是Super prime,该函数该函数1 1,否则返回,否则返回0 0/* 若n是Super prime 数返回1,否则返回0 */int IsSuperPrm(int n) 将n转换为字符串str for i=1,2, k 读取str的前i个字符,并转换为整数,存入num; 若num不是素数,返回0; 返回1;sprintf(str, %d, n); if( IsPrime( num ) = 0) return 0;num = GetNum(str, i);将数值转换为字符串,方便处理将数值转换为字符串,方便处理/ /* *将将strstr的前的前n n位转换为整数位转换为整数* */
36、 /GetNum(char str, int n) int i, d = 0; for(i = 0; i n; i+) d = d * 10 + stri 0; return d; int IsSuperPrm(int n) int i, k, num; char strN, curN; sprintf(str, %d, n); k= strlen(str); for(i = 1; i = k; i+) GetNum(str, i); if( IsPrime( num ) = 0) return 0;return 1;/ /* *将将strstr的前的前n n位转换为整数位转换为整数* */
37、/GetNum(char str, int n) char curN; strncpy(cur, str, n); curn = 0; return atoi(cur); /递归实现int IsSuperPrm(int n) if( IsPrime(n) = 0) return 0; else if( n 0) if( IsPrime(n) = 0) return 0; n = n/10; return 1;7.4 字符串应用举例7.4.1统计单词个数7.4.2多个二进制数排序7.4.3最大值多种进制7.4.4 十进制转换为r进制7.4.1 统计单词个数解法解法1: 如果一个空格后跟一个非空格
38、,一定是新单词开始: for(i=0; stri!=0; i+) 若stri是空格,stri+1不是空格,则新单词出现, count+ 问:第一个单词没算上? 答: count再加1即可!? 再问:若第一个单词前有空格会怎样?就又多了1 答:在str0不是空格的情况下count增1;解决问题:解决问题: 从键盘读入一个字符串,统计其中的单词个数。程序实现#includeint main() char str1000; int i, word, count; count = 0; gets(str); for(i = 0; stri != 0; i+) if(stri = & stri+
39、1 != ) /一个单词开始 count+; if(str0 != ) /若第一个字符不是空格 count+; printf(%dn,count); 解法2:如果一个非空格后是一个空格,一定是单词的结束: for(i=0; stri!=0; i+) 若stri不是空格,stri+1是空格,则新单词出现,count+问:最后一个单词没算上?答: count在加1即可!?再问:若最后一个单词后有空格会怎样?就又多了1答:在strlen-1不是空格的情况下count增1; 程序实现#includeint main() char str1000; int i, count, len; count =
40、0; gets(str); for(i = 0; stri != 0; i+) if(stri != & stri+1 = ) /一个单词结束 count+; len = strlen(str); if(strlen-1 != ) /若最后一个字符不是空格 count+; printf(%dn,count); 解法3:设置一个标志变量word开始word置0for(i=0; stri!=0; i+) /扫描整个字符串 若stri是空格 word置0 若stri不是空格且word=0 则新单词出现,count+; word置1; 程序实现#includeint main() char s
41、tr1000; int i, word, count; word = 0; count = 0; gets(str); for(i = 0; stri != 0; i+) if(stri = ) word = 0; if(stri != & word = 0) /新单词出现 count+; word = 1; printf(%dn,count); 课堂练习输入若干行字符,统计其字符数、行数和空白符(空格、回车、制表符)的个数欣赏大师的代码最后看一个例子,欣赏一下大师如何恰当地使用标志变量。下面的代码出自K&R,功能是统计输入的行数、单词数和字符数。单词之间的分隔符是空格、回车或
42、制表符。 #define IN 1 /*在单词内*/#define OUT 0 /*在单词外*/* 统计输入的行数、单词数和字符数 */main() int c, nl, nw, nc, state; state = OUT; nl = nw = nc = 0; while(c = getchar() != EOF) +nc; if( c = n) +nl; if( c = | c = n | c = t) state = OUT; else if(state = OUT) state = IN; +nw; printf(%d %d %dn, nl , nw , nc ); 要限制标志变量的使
43、用。在代码中轻率地使用flag之类的标志变量会使代码晦涩难度难以维护,从而变成垃圾代码。但这里,标志变量恰当地使用了state这个与问题相贴切的名字。再加上两个漂亮的符号常量IN和OUT,使得代码的含义不言自明,连注释都用不着。 7.4.2 多个二进制数排序解决问题:解决问题:输入三个二进制数,要求将这三个二进制数对应的十进制整数按从小到大的顺序输出。 思路分析:思路分析: 1)二进制数要用字符串来存储,比如一个9位的十进制数对应的二进制数长度是30位左右,如果用%d来获取就会产生类型溢出。2)调用函数BToD()将一个二进制数转化为十进制整数。 3)读入三个字符串s1,s2,s3分别调用三次
44、BToD函数得到对应的三个十进制数,对这三个十进制数排序输出。 BToD()函数的实现/*函数的功能是计算k进制的字符串str对应的十进制数*/int BToD(char str, int k);假设str: ”3456”,进制为10,将十进制的”3456”转换为十进制整数3456/d将不断左移(乘10),再加上个位d=0; 扫描字符串”3456”:i=0: d=d*10+3=3;i=1:d=3*10+4=34;i=2:d=34*10+5=345;i=3: d=345*10+6=3456假设str: ”1101”,进制为2,将二进制的”1101”转换为十进制整数/d将不断左移(乘2),再加上个
45、位d=0;扫描字符串”1101”:i=0: d=d*2+1=1;i=1:d=1*2+1=3;i=2:d=3*2+0=6;i=3: d=6*2+1=13程序7-6的main()int main(void)char str1N, str2N, str3N;int a, b, c, temp;scanf(%s%s%s, str1, str2, str3); /* 输入三个二进制数 */a = BToD(str1); /* 函数调用三次,得到三个十进制数 */b = BToD(str2);c = BToD(str3); if(a b) temp = a; a = b; b = temp; if(a c
46、) temp = a; a = c; c = temp; if(b c) temp = b; b = c; c = temp; printf(%d %d %dn, a, b, c);return 0;程序7-6的BToD()/* 把一个二进制数转换成对应的十进制数 */int BToD(char str) int i, d; d = 0; for(i = 0; stri != 0 ; i+) d = d * 2 + (stri - 0); return d;7.4.3 最大值多种进制解决问题:解决问题:输入n个非负整数,每个数的进制由其后面的数字k指定,k=2且k max, 更新max 输出m
47、ax;scanf(%s%d, a, &k);d = KToD(a, k);int KToD(char str, int k); int main(void) int i, n, k, d, max; char a50; scanf(%d, &n); max = 0; /*所有输入为非负数*/ for(i=1; i max) max = d; printf(%dn, max); return 0; 程序7-7的KToD()/*将k进制数str转换为十进制*/int KToD(char str, int k) int i, sum; sum = 0; for(i = 0; stri
48、 != 0; i+) sum = sum * k + (stri - 0); return sum; 课堂练习 改写BToD函数,将k(k = 16)进制转换为10进制。7.4.4 十进制转换为r进制问题1:将一个十进制n(0n109)转换为16进制数输出。问题2:将一个十进制n(0n109)转换为二进制数存入字符串str。问题3:将一个十进制n(0n109)转换为r(1r17)进制数存入字符串str。问题1的求解分析:分析:以十进制格式读入n,再以十六进制格式输出n#includeint main() int n; scanf(%d, &n); printf(%x , n); ret
49、urn 0;实现:实现:问题2的求解问题1的方法只适合于八进制和十六进制。下面讨论十进制向二进制的转换分析:除2取余法13262321201110高低10110难点:先得到的余数位权最低。实现方法 (1)将得到的余数依次放入数组str0、str1.,记下长度len。(2)加上字符串结束标志0(3)将字符串str逆置11010问题3的求解将十进制整数n转化为r(1r17)进制注意:由于itoa函数不是标准C语言函数,所以不能在所有的编译器中使用。这时需要自定义函数itoa。其实stdlib.h中的itoa函数可以将十进制转换为r进制:char *itoa(int value, char *str
50、ing, int r)将int整型数转化为radix进制一个字符串,并将值保存在数组string中, r的范围为2-36 #include#includeint main() int n, r; char str30; scanf(%d%d, &n, &r); itoa(n, str, r); puts(str); return 0;进制转换函数的实现要求自定义函数 DToR(int n, char str, int r),将十进制整数n转化为r(1r17)进制,存入str。DToR的实现:除r取余法100016621631614830高低难点:若r大于9,需要将数字10转换为
51、a,11转换为b.3E80如果余数 d 10 strk = d + 0; 否则 strk = d 10 + A;void dToR(int n, char str, int r) int k = 0, d; char H=0123456789ABCDEF; while(n != 0) d = n % r; strk = Hd; k+; n = n/r; strk = 0; strrev(str);void dToR(int n, char str, int r) int k, d; k = 0; while(n != 0) d = n % r; if(d 10) strk = d + 0; e
52、lse strk = d 10 + A; k+; n = n / r; strk = 0; strrev(str);善用数组简化计算! 课堂练习: 多少个圈( 1668)n给你一个整数,他到底有几个圈圈呢?比如数字“0,9,6” 都是有一个圈圈, “8” 有两个圈圈, 其他数字没有圈圈。nInput 一个整数n(1= n 0) count += zero n % 10; n /= 10; printf(%dn, count); return 0;n个字符串的最大值n输入n和n 个字符串,用二维数组保存所有字符串,并输出最大字符串。(1) 读入 n(2) for(i=0;in;i+) 读入一个字
53、符串,存入stri: gets(stri);(3) max置为空串(最小字符串):max = “”;(3) for(i = 0; i n; i+) 若stri大于max,则更新max(4) 输出字符串max 7.5 字符串数组 一维字符数组可以存储一个字符串,二维字符数组可以存储一维字符数组可以存储一个字符串,二维字符数组可以存储多个字符串,称为字符串数组。多个字符串,称为字符串数组。 字符串数组的每一行元素中都含有字符串结束符字符串数组的每一行元素中都含有字符串结束符0,因此,因此它的一行元素可以和字符串一样输入、输出及初始化。它的一行元素可以和字符串一样输入、输出及初始化。如:如:char
54、 color 10=red, blue, yellow, green, purple;字符串数组可以用二维字符数组存储。字符串数组可以用二维字符数组存储。color0color数组,有5个元素,每个是一个一维数组,可以存储一个字符串color1color2color3color4n个字符串的最大值n输入n和n 个字符串,用二维数组保存所有字符串,并输出最大字符串。(1) 读入 n(2) for(i=0;in;i+) 读入一个字符串,存入stri: gets(stri);(3) max置为空串(最小字符串):max = “”;(3) for(i = 0; i n; i+) 若stri大于max,
55、则更新max(4) 输出字符串max 程序7-9:最大字符串 char maxStrLEN = ; scanf(%d, &n); getchar(); /*处理回车,以免被后面的gets() 作为空字符串读入*/ for(i = 0; i 0) /*若stri比maxStr大则替换maxStr*/ strcpy(maxStr, stri); printf(result is:); puts(maxStr); return 0;n个字符串排序n解决问题:输入n和n 个字符串,将n个字符串按字典序排序输出。每个字符串长度不大于80。实现过程:(1) 读入 n(2) for(i=0; in;
56、 i+) 读入一个字符串,存入stri: gets(stri);(3)排序(4) for(i=0; in; i+) puts(stri); /*字符串数组排序*/for(i=1;in;i+) for(j=0;jn-i;j+) if(strj大于strj+1) strj与strj+1互换 /*字符串数组排序*/for(i=1; in; i+) for(j=0; j 0) strcpy(temp, strj); strcpy(strj, strj+1); strcpy(strj+1, temp); 课堂练习:判断字符矩阵是否相等n读入两个m行n列的字符矩阵,只含有#和*,表示两个迷宫地图。 #表示
57、红色方砖,* 表示黑色方砖。请判断两个迷宫是否完全相同。n输入m和n,表示迷宫尺寸 然后是两个m行n列的字符矩阵,#表示红色方砖,* 表示黑色方砖。n若两个矩阵完全相同,输出”yes”,否则输出”no” 善于整体处理字符串input(char mapNN, int m) /输入迷宫 for(int i = 0; i m; i+) scanf(“%s”, mapi ); /* 判断两个矩阵是否完全相同 */MapCmp(char s1NN,char s2NN, int m) for(int i = 0; i m; i+) if( strcmp(s1i, s2i) != 0) return 0; return 1; 善用函数思维 1157 连续n个1n计算机数据都是由0和1组成的,看着长长的0101001110101111011,要找出连续n个1的子串有多少个,确实麻烦,请你编程实现吧。n输入第一行为一个字符串,由0和1组成,长度小于1000;输入第二行为一个正整数n。n输出一个整数,表示连续n个的1的子串的个数。n样例输入 0101001110101111011 2n样例输出 6解题思路n搜索所有长度为n的子字符串,统计全为1的子串个数len = strlen(str)for(i = 0; i = len - n; i+) /若从stri开始的n个字符串全1 if(check(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度水利工程项目投标担保委托保证合同3篇
- 二零二五版葫芦岛市房屋继承合同范本3篇
- 基于二零二五年业绩目标的小型餐饮店面馆饭店加盟合同3篇
- 二零二五年湖南机关事业单位合同制工人医疗保险聘用合同3篇
- 二零二五版电梯门套工程安全风险评估与应急预案合同3篇
- 二零二五年电子商务纠纷解决机制合同2篇
- 二零二五年度辣椒种植与农业科技创新合作合同3篇
- 二零二五年度物流配送中心场地租赁合同BF06023篇
- 二零二五年度服装调换货及退货处理合同范本3篇
- 二零二五年度酒店住宿代理服务合同示范文本2篇
- 经方治疗脑梗塞的体会
- 新版DFMEA基础知识解析与运用-培训教材
- 制氮机操作安全规程
- 衡水市出租车驾驶员从业资格区域科目考试题库(全真题库)
- 护理安全用氧培训课件
- 《三国演义》中人物性格探析研究性课题报告
- 注册电气工程师公共基础高数辅导课件
- 土方劳务分包合同中铁十一局
- 乳腺导管原位癌
- 冷库管道应急预案
- 司法考试必背大全(涵盖所有法律考点)
评论
0/150
提交评论