字符串
基础:
实质:
以'\0'为结束标识的字符数组
定义和初始化:
char str[]={"I am happy"};
或
char str[]="I am happy";
定义方法 | 内存中实质存储的元素 | 解析 |
char str1[]={'h','a','p','p','y'}; | h a p p y | 字符数组的长度为5 |
char str2[]={'h','a','p','p','y','\0'}; | h a p p y \0 | 字符数组的长度为6,字符串长度为5,最后一个元素\0作为字符串的标识 |
char str3[10]={'h','a','p','p','y','\0'}; | h a p p y \0 | 字符数组的长度为10,但字符串的长度为5,因为读取字符串时,遇到\0就会中止读取.所以\0后即使仍有空间,也不会被算入字符串的长度. |
注:虽然char str[20]="I am happy";是正确的,但char str[20];str="I am happy";却是错误的!赋值和初始化是有区别的 !
输入输出
输出:
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*
这个程序用来测试字符串的输出
*/
void p1(char[]);
void p2(char[]);
void p3(char[]);
void p4(char[]);
int main()
{
char str[]="I am happy";
printf("p1:");
p1(str);
printf("\np2:");
p2(str);
printf("\np3:");
p3(str);
printf("\np4:");
p4(str);
return 0;
}
void p1(char str[])
{
int i;
for(i=0;i<10;i++)
{
printf("%c",str[i]);
}
}
void p2(char str[])
{
int i=0;
while(str[i]!='\0')
printf("%c",str[i++]);
}
void p3(char str[])
{
puts(str);
}
void p4(char str[])
{
printf("%s",str);
}
结果:
解析:
1.p1是使用最传统的方法输出字符串,但显然十分的效率低下。而且适应性很差。
2.p2巧用了字符串以/0结尾的设定,简化、优化了输出的过程。
3.p3直接调用C语言内置的字符串输出函数puts。
4.p4使用了格式控制符%s,通过printf函数输出了字符串。
输入:
字符串的输入有三种手法:
1.
for(i=0;i<20;i++)
scanf("%c",&str[i]);
使用scanf函数一个个获取字符,并存入字符数组,是最原始的操作方法。
2.
scanf("%s",str);
使用scanf函数直接获取字符串,并存入字符数组,是相对高效的方法
注1:因为数组名代表的是数组首元素的地址值,所以不需要使用取地址运算符
注2:scanf函数,一旦遇到空格、\t或回车,就会判定字符串输入结束!所以如果碰到输入的字符串带空格,这种方法就只会将空格前的字符串读入!
3.
gets(str);
使用C语言内置的字符串读取函数gets,某种大多数情况下是最高效的方法。
注:gets函数,遇到空格、\t不结束输入,只有遇到回车才判定字符串输入结束!所以适合用于读入带空格的字符串!
指针和字符串
原理:
因为字符串实际上就是以\0结尾的字符数组,所以同样可以用指针法访问字符串。
如:
char str[]="I am happy";
char *s;
s=str;
具体应用方法和使用指针法访问整型数组、字符型数组相同,不做赘述。
注:char *s="I am happy";这种形式是可行的。
诸如:
char *s;
gets(s);
puts(s);
犯了野指针的错误,务必不要触碰。
拓展内容
字符串的长度:
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用来获取字符串的长度*/
int Getlength(char*);
int Getlength2(char*);
int Getlength3(char*);
int main()
{
char str[50];
printf("输入字符串");
gets(str);
printf("这一句中有%d个字符.\n",Getlength(str));
return 0;
}
int Getlength(char *str)
{
int n=0;
while(str[n]!='\0')
{
n++;
}
return n;
}
int Getlength2(char *str)
{
int n=0;
while(str[n++]!='\0');
n--;
return n;
}
int Getlength3(char *str)
{
int n;
for(n=0;str[n]!='\0';n++);
return n;
}
结果:
解析:
1.如上,成功输出了字符串的长度,这个长度是包括字母、数字、空格、符号但不包括用于字符串结尾的\0的!
2.Getlength2和Getlength3都是稍微改变形态的获取长度的核心代码。虽然形态不同,但他们的原理是相同的。
获取字符串中每种字母出现的次数
代码示例:
#include <stdio.h>
#include <stdlib.h>
/*这个程序用来统计输入的字符串中各个小写字母出现的次数*/
void detect(char*,int*);
int main()
{
char str[50];
int i,n[26]={0};//此处是一个初始化的小技巧,这种写法能直接给数组中所有的元素都赋值为0
printf("输入字符串:");
gets(str);
detect(str,n);
for(i=0;i<26;i++)
if(n[i]!=0)
printf("%c:%d\n",i+'a',n[i]);//A处
return 0;
}
void detect(char *str,int *n)
{
int i=0;
while(str[i]!='\0')
{
if(str[i]>='a'&&str[i]<='z')
n[str[i]-'a']++;//B处
i++;
}
}
结果:
解析:
1.此代码的原理十分简单,但核心是代码中A、B两处的处理,通过ASCII码的巧妙运算完美的实现了字母和数字的关系转换。
2.如果要统计大写字母,只需要将'a'换成'A'。统计数字同理。核心是掌握ASCII码与整数的换算。