字符数组:元素为字符类型的数组
字符串:最后一个元素以'\0'或整数0(是整数0,而不是字符'0')结束的字符数组,可以用字符串函数做运算。
0标志着字符串的结束,但他不是字符串的一部分,计算字符串长度时不包含这个0.
char word[]={'H','e','l','l','o','!'};
//这就是一个字符数组,存储长度=数组长度=6,有效长度为6
char word2[]={'H','e','l','l','o','!','\0'};
//以'\0'结束则变成了一个字符串,可以以字符串的方式做计算,本质上还是数组,存储长度=数组长度=7,有效长度为6。
char word2[]={'H','e','l','l','o','!',0};
//这样也是一个字符串,但是0表示整数0,占2或4个字节,'\0'必然占一个字节
char c[3]={'a','b','c'}
char c[5] = {'a','b'}
其余元素会自动赋一个空字符'\0'
| c[0] | c[1] | c[2] | c[3] | c[4] |
|---|---|---|---|---|
| 'a' | 'b' | '\0' | '\0' | '\0' |
可以不用填写元素个数,这样编译器会自动认为这个字符数组元素个数为3个
char c[]={'a','b','c'}
虽然说字符数组不要求最后一个字符为'\0',甚至可以不包括'\0',但是我们为了能用字符串的方式操作字符数组,通常在末尾加个'\0'
//char *str = "Hello"后续介绍
char words[] = {"Hello"};//编译器会自动补'\0',导致数组长度为6
char word[] = "Hello";//编译器会自动补'\0',导致数组长度为6
等价写法:
char word[]={'H','e','l','l','o','\0'}
//等价于后边加一个'\0'的写法
char line[10] = "Hello";//编译器会自动补5个'\0'
和普通数组一样
数组名[下标]引用
指针和数组有着密切的联系,而字符串在存储上是字符数组。所以指针和字符串有着天然联系。
# include <stdio.h>
int main(void)
{
char word[]="I love China!";
printf("方法1: %s\n",word);//法1
char * string1 = "I love China!";
printf("方法2: %s\n",string1);//法2
char * string2;
string2 = word;
printf("实验: %s\n",string2);//可以看出字符指针变量名和字符数组名性质一样
/*
"I love China!"是一个字符串,但本质上是一个字符数组。
可以用数组的方式进行操作
方法1 就是利用字符串的数组特性,通过数组名进行引用,输出字符串。
方法2
字符指针变量 string1 是 char * 类型
表示string1可以存放的是一个 char 类型数据的地址。
如果指向字符串,它存放的就是字符串的首地址。
所以这个字符指针变量的名字和数组名一样,都是存放首地址的。
由于我们知道字符串有一个特性就是结尾是'\0'
所以即使只存放一个首地址,指针也能指向整个字符串,因为它知道什么时候该结束!
*/
return 0;
}
单个字符输入输出: %c
以字符串格式输入输出: %s
输出示例
int main(void)
{
char a[]={'A','P','\0','a','o'};
int i;
printf("%s\n",a);
for(i=0;i<5;++i)
{
printf("%c",a[i]);
}
printf("\n");
return 0;
}
//输出结果
AP
AP ao
注意
输入示例
1. 一个字符串
int main(void)
{
char a[10];
scanf("%s",a);
int i;
for(i=0;i<5;++i)
{
printf("%c",a[i]);
}
printf("\n");
return 0;
}
//运行后
输入:hello(回车后系统自动加一个'\0')
输出:hello
2. 多个字符串
int main(void)
{
char a[10];
char b[10];
char c[10];
scanf("%s%s%s",a,b,c);
printf("%s%s%s",a,b,c);
return 0;
}
//运行后
输入:how(空格)are(空格)you
输出:howareyou
注意:
scanf 用在输入字符串就不要加取地址符&了,因为数组的数组名本身就是数组元素的首地址
char *str = "Hello";
char word[] = "Hello";
char line[10] = "Hello";//占6个位置,编译器会自动补个0
int main(void)
{
char c[]= "China";
printf("%s",c);
printf("_____");
puts(c);
printf("_____");
return 0;
}
//输出:
China_____China
_____
可见
puts 把结束的'\0'转换成了'\n'来输出,也就是说puts输出后会自动换行
gets的作用是输入一个字符串,并返回该字符串的首地址
int main(void)
{
char c[10];
printf("%o\n",gets(c));
return 0;
}
//输出:
how
30377026
注意:
puts和gets只能输入一个字符串,不能同时输入多个
把字符串2 连接到字符串1 末尾
int main(void)
{
char a[30]="How are ";
char b[5]="you";
strcat(a,b);
printf("%s",a);
return 0;
}
//输出:
How are you
注意:
要存放连接结果的那个字符串也就是字符串1,一定要足够长。
连接前,字符串1后面后很多空的'\0',连接后全部取消,字符串2末尾的多个'\0'保留。
作用:把字符串2 的内容复制给字符串1
int main(void)
{
char str1[10]="1111111111";
char str2[10]="world";
printf("复制前str1:%s",str1);
strcpy(str1,str2);
printf("\n复制后str1:\n");
int i;
for(i=0;i<10;++i)
{
printf("%c",str1[i]);
}
printf("\n");
return 0;
}
//输出:
复制前str1:1111111111
复制后str1:
world 1111
注意
一、要存放复制结果的那个字符串也就是字符串1,一定要足够长,其长度不应小于字符串2错误
char a[5];
char b[5]="abc";
a=b;
a,b都是一个字符数组名,是一个地址常量,不能改变值。 只能通过strcpy、strncpy函数进行赋值。
strncpy
指定字符串2的前n个字符复制到字符串1里
int main(void)
{
char str1[10]="1111111111";
char str2[10]="world";
printf("复制前str1:%s",str1);
strncpy(str1,str2,3);
printf("\n复制后str1:\n");
int i;
for(i=0;i<10;++i)
{
printf("%c",str1[i]);
}
printf("\n");
return 0;
}
//输出:
复制前str1:1111111111
复制后str1:
wor1111111
可以看见这次复制字符串2的时候没有'\0'
用法
char str1[]="APP";
char str2[]="APPLE";
strcmp(str1,str2);
strcmp("APP","APPLE");
strcmp(str1,"APPLE");
字符串比较规则:
将两个字符串自左至右逐个字符比较(按ASCII字符的大小比较),直到遇到不同字符,或者出现'\0'为止
如果字符全部相同,则认为两个字符串相等,函数值为0 若字符不完全相同,则以第一对不相同的字符为准,若字符串1>字符串2,返回正整数;字符串2>字符串1,返回负整数。
int main(void)
{
char str1[]="APP";
char str2[]="APPLE";
printf("%d\n",strcmp(str1,str2));
return 0;
}
//结果
-1
注意
一、英文小写字母 > 英文大写字母int main(void)
{
char str1[10]="APP";
printf("%d\n",strlen(str1));
return 0;
}
//结果
3
很明显只输出有效字符个数
strlwr —— 将字符串大写字母全部转成小写 strupr —— 将字符串小写字母全部转成大写
int main(void)
{
char str1[10]="APP";
char str2[]="Apple";
printf("%s\n",strlwr(str1));
printf("%s\n",strupr(str2));
return 0;
}
//结果
app
APPLE
注意
字符串处理函数是库函数,并不是C语言本身的组成部分,而是各编译系统为方便用户使用提供的公共函数,不同编译系统在函数名和使用方法上可能会不同,但常用的几个都一样。本文章使用limfx的vsocde插件快速发布