假如想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量做参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。在函数调用实现字符串的复制。
解题思路:
定义一个函数 copy_string 用来实现字符串复制的功能,在主函数中调用此函数,函数的形参和实参可以分别用字符数组名或字符指针变量。分别编程,以供分析比较。
编写程序 1-1.c 用字符数组名作为函数参数,程序 1-2.c 用字符型指针变量作实参,程序 1-3.c 用字符指针变量作形参和实参。
#include<stdio.h>
int main()
{
void copy_string(char from[],char to[]);
char a[] = "I am a teacher";
char b[] = "You are a programmer";
printf("string a=%s\nstring b=%s\n",a,b);
printf("copy string a to string b:\n");
copy_string(a,b);
printf("\nstring a=%s\nstring b=%s\n",a,b);
return 0;
}
void copy_string(char from[],char to[])
{
int i = 0;
while(from[i]!='\0')
{
to[i] = from[i];
i++;
}
to[i] = '\0';
}
copy
编写源程序 1-2.c:
**
#include<stdio.h>
int main()
{
void copy_string(char from[],char to[]);
char a[] = "I am a teacher";
char b[] = "You are a programmer";
char *from = a,*to = b;
printf("string a=%s\n string b=%s\n",a,b);
printf("copy string a to string b:\n");
copy_string(from,to);
printf("\n string a=%s\n string b=%s\n",a,b);
return 0;
}
void copy_string(char from[],char to[])
{
int i = 0;
while(from[i]!='\0')
{
to[i] = from[i];
i++;
}
to[i] = '\0';
}
copy
**
编写源程序 1-3.c:
#include<stdio.h>
int main()
{
void copy_string(char from[],char to[]);
char *a = "I am a teacher";
char b[] = "You are a programmer";
char *p = b;
printf("string a=%s\n string b=%s\n",a,b);
printf("copy string a to string b:\n");
copy_string(a,p);
printf("\n string a=%s\n string b=%s\n",a,b);
return 0;
}
void copy_string(char *from,char *to)
{
for(;*from!='\0';from++,to++)
*to = *from;
*to = '\0';
}
copy
运行三个程序,可以看出,结果是一样的。
结果分析·
程序 1-1.c。将数组 a 复制到数组 b 后,未能全部覆盖 b 数组原有内容。b 数组最后 3 个元素仍保留原状。在输出 b 时由于按 %s 输出,遇到 ‘\0’ 就会结束,因此第一个 ‘\0’ 后的字符不输出。
程序 1-2.c。copy_string 不变,在 main 函数中定义字符指针变量 from 和 to,分别指向两个字符数组 a 和 b。 指针变量 from 的值是 a 数组首元素的地址,指针变量 to 的值是 b 数组首元素的地址。它们作为实参,把 a 数组首元素的地址和 b 数组首元素的地址传递给形参数组名 from 和 to(它们实质也是指针变量)。
程序 1-3.c。形参改用 char * 型变量(即字符指针变量)。在程序(1)和(2)中 copy_string 函数的参数用字符数组名,其实编译系统是把字符数组名按指针变量处理的,只是表示形式不同。
用字符数组和字符指针变量都能实现字符串的存储和运算,但它们两者之间是有区别的,主要为以下几点:
1.字符数组由若干元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1个字符的地址),绝不是将字符串放到字符指针变量中。
2.赋值方式。可以对字符指针变量赋值,但不能对数组名赋值。对字符指针变量赋值:
char *a;
a = "I love shiyanlou!"; //将字符串首元素地址赋给指针变量,合法。但是赋给a的不是字符串,只是一个字符串首元素的地址。
给a字符指针变量字符串首元素的地址,然后通过%s打印自动将地址加一,直到遇到‘\0’为止。
不能用以下办法对字符数组名赋值:
char str[14];
str[0] = 'I'; //合法,对字符数组元素赋值
str = "I love Shiyanou"; //非法,数组名是地址,是常量,不能被赋值
3.存储单元的内容。编译时为字符数组分配若干存储单元,以存放各元素的值,而对字符指针变量,只分配一个存储单元