这几个函数包含了类型、运算符和表达式在内的许多知识点,例子中使用了具体主函数来检验其效果,各个函数都有其十分有用的功能:
strlen - 计算字符串长度 atoi - 将数字字符串转换为对应数值 lower - 将大写字母转换为小写 squeeze - 将与要求相符的字符从字符串中删去 strcat - 将两个字符串连接起来 getbit - 得到对应二进制位数的另一个数 bitcount - 得到数值对应二进制数中1的位数
2-1 strlen函数2-2 atoi函数2-3 lower函数2-4 强制类型转换2-5 squeeze函数2-6 strcat函数2-7 squeeze函数改2-8 getbits函数2-9 bitcount函数2-10 lower函数改参考学习资料
2-1 strlen函数
/×
strlen函数:返回s的长度×/
#include <stdio.h>
int Strlen(
char s[])
{
int i;
i =
0;
while(s[i] !=
'\0')
++i;
return i;
}
int main()
{
char s[] =
"Hello world";
printf(
"%d\n",Strlen(s));
return 0;
}
注意点:
标准头文件string.h中声明了strlen和其他字符串函数,将其包含可直接使用在C语言标准中,有些通用函数被定义为built-in function(内建函数);即使不包含含有该函数的头文件,当我们想自己实现其功能时也可能会出现warning: conflicting types for built-in function ‘puts’的错误提示,所以上述程序将函数名strlen改为了Strlen避免冲突
2-2 atoi函数
#include <stdio.h>
#define MAXLINE 1000
int atoi(
char s[])
{
int i,n;
n =
0;
for(i =
0;s[i] >=
'0' && s[i] <=
'9';++i)
n =
10*n+(s[i]-
'0');
return n;
}
int main()
{
char line[MAXLINE];
char c;
int i;
i =
0;
while((c = getchar()) !=
'\n'){
line[i] = c;
++i;
}
if(c ==
'\n')
line[i] = c;
printf(
"%d\n",atoi(line));
return 0;
}
注意点:
char类型就是较小的整型变量,这为某些字符转换提供了很大的灵活性‘0’、 ‘1’等在字符集中对应的数值是一个连续的递增序列且对应数值为0、 1等
2-3 lower函数
#include <stdio.h>
int lower(
int c)
{
if(c >=
'A' && c <=
'Z')
return c +
'a' -
'A';
else
return c;
}
int main()
{
char s[
1000];
int c,i;
i =
0;
while((c = getchar()) !=
'\n')
{
s[i] = c;
i++;
}
if(c ==
'\n')
s[i] = c;
for(i=
0;s[i] !=
'\n';i++)
s[i] = lower(s[i]);
printf(
"%s\n",s);
return 0;
}
注意点:
ASCII字符集中,大写字母与对应小写字母作为数字值来说具有固定的间隔,每个字母表都是连续的,也就是说A~Z之间只有字母(这一点对于EBCDIC字符集来说是不成立的),所以可以用c+ ‘a’ - ‘A’赋值给c来达到将c替换为小写形式的功能也可以用c+ ‘A’ - ‘a’赋值给c来达到将c替换为大写形式(前提是c为小写形式)的功能,得到一个跟上述函数功能相反的函数,标准头文件ctype.h中被定义了一组与字符集无关的测试和转换函数,其中就包含了将c替换为大写形式(前提是c为小写形式)的tolower函数
2-4 强制类型转换
#include <stdio.h>
#include <math.h>
int main()
{
int c;
scanf(
"%d",&c);
printf(
"%f\n",
sqrt(c));
return 0;
}
注意点:
强制类型转换格式为:(类型名)表达式;如程序中的sqrt(c)的函数原型为sqrt(double(c))sqrt函数在头文件math.h中,由于math.h不在标准库而在数学库中,用gcc编译器编译时格式为:gcc *.c -lm
2-5 squeeze函数
#include <stdio.h>
void squeeze(
char s[],
int c)
{
int i,j;
for(i = j =
0;s[i] !=
'\0';i++)
if(s[i] != c)
s[j++] = s[i];
s[j] =
'\0';
}
int main()
{
char s[] =
"1233211234567";
int c =
'1';
squeeze(s,c);
printf(
"%s\n",s);
return 0;
}
注意点:
自增、自减运算符在不同地方前缀后缀效果不同,上述squeeze函数中进行下列语句替换效果将完全相同,但明显前者更为简洁
if(s[i] != c)
s[j++] = s[i];
if(s
[i] != c)
{
s[j] = s[i];
j++;
}
文本结束符 ‘\0’之后的字符在printf函数中不会再被打印自增、自减运算符在许多地方都有出色的应用,比如下面的strcat函数
2-6 strcat函数
#include <stdio.h>
void Strcat(
char s[],
char t[])
{
int i,j;
i = j =
0;
while(s[i] !=
'\0')
i++;
while((s[i++] = t[j++]) !=
'\0')
;
}
int main()
{
char s[
30] =
"Let's compile ";
char t[] =
"a c program";
Strcat(s,t);
printf(
"%s\n",s);
return 0;
}
注意点:
函数中包含的许多自增运算符被包含在while循环语句中,这时要注意即使没有执行部分,循环体也要加入 ‘;’来表示结束上面为一个较为简单不涉及指针的strcat函数,在头文件string.h中已经包含了一个拥有返回一个指向新字符串的指针的strcat函数使用strcat函数时切记要注意s的空间要足够大以容纳t字符串
2-7 squeeze函数·改
#include <stdio.h>
void squeeze(
char s[],
char t[])
{
int i,j,k,l;
i = j = k = l =
0;
for(i=
0;s[i] !=
'\0';i++){
k =
0;
for(j=
0;t[j] !=
'\0';j++)
k += (s[i] == t[j]);
if(k ==
0)
s[l++] = s[i];
}
s[l] =
'\0';
}
int main()
{
char s[] =
"1233211234567";
char t[] =
"12";
squeeze(s,t);
printf(
"%s\n",s);
return 0;
}
注意点:
利用了表达式结果为真时数值为1,为假时数值为0,将s中的字符与t中的字符一一对比,以相等为真,值为1,不等为假,值为0,用变量k储存;当s中字符不等于t中任一字符时,k为0,否则则不为0,使用条件语句判断k值大小将字符重返字符串s
2-8 getbits函数
#include <stdio.h>
unsigned getbits(
unsigned x,
int p,
int n)
{
return (x >> (p-n)) & ~(~
0 << n);
}
int main()
{
printf(
"%d\n",getbits(
441,
5,
3));
return 0;
}
注意点:
441对应二进制为110111001,变化如下:向左移动5位 1101 11001;向右移动3位1101110 01。得到了前后相差为110,则对应为6;<< 和 >>为左右移位符号,右接移动位数~0表示对0进行各位取反& 为按位与,即同位置均为1则取1,否则取0另外还有双目运算符按位或 | :同位均为0则取0,否则取1;按位异或 ^ :各位取不同取1,否则取0单目运算符按位取反 ~ :各位求反(单目运算符也称一元运算符)
2-9 bitcount函数
#include <stdio.h>
int bitcount(
unsigned x)
{
int n;
for(n=
0;x !=
0;x >>=
1)
if(x &
01)
n++;
return n;
}
int main()
{
printf(
"%d\n",bitcount(
441));
return 0;
}
注意点:
x >>= 1相当于x = x >> 1,这里是使用了赋值运算符,即expr1 op= expr2等价于expr1 = (expr1)op(expr2),这是让程序更为简洁的一个好办法如果将x >>= 1打成了x >> 1则程序将无法达到预期效果
2-10 lower函数·改
#include <stdio.h>
int lower(
int c)
{
return(c >=
'A' && c <=
'Z')?c +
'a' -
'A':c;
}
int main()
{
char s[
1000];
int c,i;
i =
0;
while((c = getchar()) !=
'\n')
{
s[i] = c;
i++;
}
if(c ==
'\n')
s[i] = c;
for(i=
0;s[i] !=
'\n';i++)
s[i] = lower(s[i]);
printf(
"%s\n",s);
return 0;
}
注意点:
lower函数中将原本的if-else语句替换为了条件表达式,结构为expr1 ? expr2 : expr3,计算方式为:先计算expr1,若其值为真,则计算expr2的值,否则计算expr3的值将main函数中的s[i] = lower(s[i])替换为s[i] = (s[i] >= ‘A’ && s[i] <= ‘Z’) ? s[i] + ‘a’ - ‘A’ : s[i] 而选择不定义lower函数也可以实现本程序效果
参考学习资料
《C程序设计语言》