例题 : 定义一个字符数组,在其中存放字符串“I love China!”,输出该字符串和第8个字符。
解题思路:
定义字符数组string,对它初始化,
由于在初始化时字符的个数是确定的,
因此可不必指定数组的长度。
用数组名string和输出格式%s可以输出整个字符串。
用数组名和下标可以引用任一数组元素。
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
char a[]="I Love China.";
printf("%s\n",a);
printf("字符串的第八个字符为:%c",a[7]);//a[7]即第八个字符(空格也算一个字符)
}
//定义一个指针变量*p=sjxnwj,则p[3]也能够输出,即输出n
结果显示:
I Love China.
字符串的第八个字符为:C
注意事项:
下面为错误写法,是因为string[3]='A'不能改变上面已经定义好的字符串内容
但是可以输出字符串中的第几位字符,例如printf("%c",string[4]);即第五位字符v
void main()
{
char *string;
string="I love China!";
string[3]='A';
printf("%s",string);
}
上述对于指针变量而言不能改变字符串内容,但是对于数据就可以发生改变
void main()
{
char string[]="I love China!";
string[3]='A';
printf("%s\n",string);
printf("%c\n",string[3]);
printf("%c",string[7]);
}
结果显示:
I lAve China!//此时o已经变为了A
A
C
例题:通过字符指针变量输出一个字符串。
解题思路:
可以不定义字符数组,只定义一个字符指针变量,
用它指向字符串常量中的字符。通过字符指针变量输出该字符串。
/* Note:Your choice is C IDE */
#include "stdio.h"
void main()
{
char *p="I love China!!!";
//相当于 char *p; p="I love China!!!"两个句式组成
printf("%s",p);
}
结果显示:
I love China!!!
字符串内容的替换
/* Note:Your choice is C IDE */
#include "stdio.h"
void mc();
void main()
{
char *string="I love China!";
printf("%s\n",string);
string="I am a student.";
printf("%s\n",string);
}
结果显示:
I love China!
I am a student.
错误实例演示:
因为定义好一个数组,内存空间就确定了,不可以发生改变,所以不能直接赋给素组一行字符串
错误实例1
void main()
{
char string[20];
string="I love China!";
printf("%s",string);
}
错误实例2
void main()
{
char string[];
string[]="I love China!";
printf("%s",string);
}
错误实例3
void main()
{
char string[];
string="I love China!";
printf("%s",string);
}
错误实例4
void main()
{
char string[20];
string[]="I love China!";
printf("%s",string);
}
例题 :将字符串a复制为字符串b,然后输出字符串b。
解题思路:定义两个字符数组a和b,
用“I am a student.”对a数组初始化。
将a数组中的字符逐个复制到b数组中。
可以用不同的方法引用并输出字符数组元素,
今用地址法算出各元素的值
/* Note:Your choice is C IDE */
下标法、地址法
#include "stdio.h"
void main()
{
char a[]={"I am beautiful"},b[30];
int i;
for (i=0;*(a+i)!='\0';i++)//*(a+i)即表示为a[i]
*(b+i)=*(a+i);//b[i]=a[i]
*(b+i)='\0';//b[i]='\0'
printf("数组a中的字符串为:%s\n",a);
printf("数组b中的字符串为:%s\n",b);
// 上面一行输出语句的代码可以用以下代码表示
// for(i=0;b[i]!='\0';i++)
// printf("数组b中的字符串为%c",b[i]);
}
结果显示
数组a中的字符串为:I am beautiful
数组b中的字符串为:I am beautiful
/* Note:Your choice is C IDE */
指针变量法
#include "stdio.h"
void main()
{
char a[]={"You Love me"},b[30],*p1,*p2;
p1=a;
p2=b;
for(p1=a;*p1!='\0';p1++,p2++)
*p2=*p1;//用循环一个一个的将p1指向的a数组中的内容传递给p2指向的b数组中
*p2='\0';//因为a数组中的'\0'没传给b数组,所以单独写出这一行代码将'\0'写入b数组中
printf("数组a中的字符串为:%s\n",a);
printf("数组b中的字符串为:%s\n",b);
}
结果显示:
数组a中的字符串为:You Love me
数组b中的字符串为:You Love me
用方法的调用的方式进行 下标法、地址法
/* Note:Your choice is C IDE */
#include "stdio.h"
void string(char a[],char b[]);
void main()
{
char a[]={"I am beautiful"},b[30];
string(a,b);
printf("数组a中的字符串为:%s\n",a);
printf("数组b中的字符串为:%s\n",b);
// 上面一行输出语句的代码可以用以下代码表示
// for(i=0;b[i]!='\0';i++)
// printf("数组b中的字符串为%c",b[i]);
}
void string(char a[],char b[])
{
int i;
for (i=0;*(a+i)!='\0';i++)//*(a+i)即表示为a[i]
*(b+i)=*(a+i);//b[i]=a[i]
*(b+i)='\0';//b[i]='\0'
}
结果显示
数组a中的字符串为:I am beautiful
数组b中的字符串为:I am beautiful
用方法调用的方式进行 指针变量法
/* Note:Your choice is C IDE */
#include "stdio.h"
void string(char *p1,char *p2);
void main()
{
char a[]={"You Love me"},b[30],*p1,*p2;
p1=a;
p2=b;
string(p1,p2);
printf("数组a中的字符串为:%s\n",a);
printf("数组b中的字符串为:%s\n",b);
}
void string(char *p1,char*p2)
{
for(;*p1!='\0';p1++,p2++)
*p2=*p1;
*p2='\0';
}
结果显示:
数组a中的字符串为:You Love me
数组b中的字符串为:You Love me
用方法调用的方式 用strcpy函数方法
void copy(char *p1,char *p2);
int main()
{ char a[]="Study don't love me",b[]="Study make me happy !!!",*p1,*p2;
p1=a;
p2=b;
copy(p1,p2);
printf("%s\n",a);
printf("%s",b);
}
void copy(char *p1,char *p2){
strcpy (p1,p2);//将p2中的内容复制给p1,不管p1原本是什么内容,复制后原本内容被完全覆盖
}
例题 : 用函数调用实现字符串的复制。
解题思路:
定义一个函数copy_string用来实现字符串复制的功能,
在主函数中调用此函数,
函数的形参和实参可以分别用字符数组名或字符指针变量。
分别编程,以供分析比较。
用字符数组名作为函数参数
/* Note:Your choice is C IDE */
#include "stdio.h"
void copy(char a[],char b[]);
void main()
{
//注意:数组a的内容传给b数组,要保证b数组足够大,能够足够储存a中的所有内容
char a[]="come on";
char b[]="Where are you?";
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
printf("将a的内容复制到b中\n");
copy(a,b);//用字符数组名作为函数实参
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
}
void copy(char a[],char b[])//形参为字符数组
{
int i=0;
while(a[i]!='\0'){
b[i]=a[i];
i++;
}
b[i]='\0';//若不加这一行代码,最终数组b中的内容为come onre you?
//原因是b数组把a数组中的内容复制完后,b数组自身还有内容,不遇到'\0'仍会把b数组剩余的内容继续输出
}
结果显示:
数组a中的内容为:come on
数组b中的内容为:Where are you?
将a的内容复制到b中
数组a中的内容为:come on
数组b中的内容为:come on
用字符型指针变量作实参
#include "stdio.h"
void copy(char a[],char b[]);
void main()
{
char a[]="come on";
char b[]="Where are you?";
char *p1,*p2;
p1=a;
p2=b;
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
printf("将a的内容复制到b中\n");
copy(a,b);//用字符型指针变量作为函数实参
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
}
void copy(char a[],char b[])//形参为字符数组
{
int i=0;
while(a[i]!='\0'){
b[i]=a[i];
i++;
}
b[i]='\0';
}
结果显示:
数组a中的内容为:come on
数组b中的内容为:Where are you?
将a的内容复制到b中
数组a中的内容为:come on
数组b中的内容为:come on
用字符指针变量作形参和实参
#include "stdio.h"
void copy(char *a,char *b);
void main()
{
char a[]="come on";
char b[]="Where are you?";
char *p1,*p2;
p1=a;
p2=b;
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
printf("将a的内容复制到b中\n");
copy(a,b);//用字符型指针变量作为函数实参
printf("数组a中的内容为:%s\n数组b中的内容为:%s\n",a,b);
}
void copy(char *a,char *b)//形参为字符数组
{
for(;*a!=0;a++,b++)
*b=*a;
*b='\0';
}
结果显示:
数组a中的内容为:come on
数组b中的内容为:Where are you?
将a的内容复制到b中
数组a中的内容为:come on
数组b中的内容为:come on
对上面的copy函数的代码有多种改进方案
方案1:
void copy(char *a,char *b)//形参为字符数组
{
while((*b=*a)!='\0'){
a++;
b++;
}
}
方案2:
void copy(char *a,char *b)//形参为字符数组
{
while((*b++=*a++)!='\0');//先将*a赋值给*b,然后再使a,b自增
}
方案3:
void copy(char *a,char *b)//形参为字符数组
{
while(*a!='\0')
*b++=*a++;
*b='\0';
}
方案4:
void copy(char *a,char *b)//形参为字符数组
{
//由于字符可以用其ASCII码来代替(例如,“ch='a'”可用“ch=97”代替)
//故while(*a!='0')可以用while(*a!=0)代替('\0'的ASCII码为0)
while(*a)
*b++=*a++;
*b='\0';
}
方案5:
void copy(char *a,char *b)//形参为字符数组
{
while (*b++=*a++);//*b++=*a++等价于*b++=*a++)!='\0'
}
方案6:
void copy(char *a,char *b)//形参为字符数组
{
for(;(*b++=*a++)!='\0';);
//或者写成for(;*b++=*a++;);
}
方案7:
//也可以用字符数组名作函数形参,在函数中另定义两个指针变量p1,p2
void copy(char a[],char b[])
{
char *p1,*p2;
p1=a;
p2=b;
while((*p2++=*p1++)!='\0');
//while语句可以改为while(*p2++=*p1++);
}
使用字符指针变量和字符数组的比较
用字符数组和字符指针变量都能实现字符串的存储和运算,
但它们二者之间是有区别的,不应混为一谈,主要有以下几点
(1) 字符数组由若干个元素组成,每个元素中放一个字符,
而字符指针变量中存放的是地址(字符串第1个字符的地址),
决不是将字符串放到字符指针变量中。
(2) 赋值方式。可以对字符指针变量赋值,但不能对数组名赋值。
char *a; a="I love China!"; 对
char str[14];str[0]='I'; 对
char str[14]; str="I love China!"; 错
(3)初始化的含义
char *a="I love China!";与
char *a; a="I love China!";等价
char str[14]= "I love China!";与
char str[14];
str[]="I love China!"; 不等价,而且是错误写法
(4) 存储单元的内容
编译时为字符数组分配若干存储单元,以存放各元素的值,
而对字符指针变量,只分配一个存储单元
char *a; scanf("%s",a); 错
char *a,str[10];
a=str;
scanf ("%s",a); 对
(5) 指针变量的值是可以改变的,
而数组名代表一个固定的值(数组首元素的地址),不能改变。
例如 char *a="I love China!";
a=a+7;
printf("%s\n",a); 正确
又例如 char a[]="I love China!";
a=a+7;
printf("%s\n",a); 错误
(6) 字符数组中各元素的值是可以改变的,
但字符指针变量指向的字符串常量中的内容是不可以被取代的。
char a[]="House",*b="House";
a[2]='r'; 对
b[2]='r'; 错
(7) 引用数组元数
对字符数组可以用下标法和地址法引用数组元素(a[5],*(a+5))。
如果字符指针变量p=a,
则也可以用指针变量带下标的形式和地址法引用(p[5],*(p+5))。
char *a="I love China!";
则a[5]的值是第6个字符,即字母'e'
(8)用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。
char *format;
format="a=%d,b=%f\n";
printf(format,a,b);
相当于
printf("a=%d,b=%f\n",a,b);
format是指针变量,存储的是字符串的地址,
printf函数第一个参数的类型就是char *类型,和format类型一致