一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
字符串的引用方式
想引用一个字符串,可以用以下两种方法:
- 用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明"%s"输出该字符串
- 用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量 "%s" 是输出字符串时所用的格式符,在输出项中给出字符指针变量名string,则系统会输出string所指向的字符串第1个字符,然后自动使string加1,使之指向下一个字符,再输出该字符......如此知道遇到字符串结束标志'\0'为止。注意,在内存中,字符串的最后被自动加了一个'\0', 因此在输出时能确定输出的字符到何时结束。"%s" 可以对一个字符串进行整体的输入输出。
/**
* 将字符串a复制到字符串b,然后输出字符串b
* */
// 地址法算出各元素的值:
char a[] = "I am a student.", b[20]; // 定义字符数组
int i;
for (i = 0; *(a+i) != '\0'; i++)
*(b+i) = *(a+i); // 将a[i]的值赋给b[i]
*(b+i) = '\0'; // 在b数组的有效字符之后加'\0'
printf("string a is: %s\n", a);
printf("string b is: ");
for (i = 0; b[i] != '\0'; i++)
printf("%c", b[i]);
printf("\n");
// 用指针变量处理上述问题
char aa[] = "I am a boy.", bb[20], *p1, *p2;
p1 = aa;
p2 = bb; // p1, p2分别指向a数组和b数组中的第一个元素
for (; *p1 != '\0'; p1++, p2++) // p1, p2 每次自加1
*p2 = *p1; // 将p1所指向的元素的值赋给p2所指向的值
*p2 = '\0'; // 在复制完全部有效字符后加'\0'
printf("string aa is: %s\n", aa);
printf("string bb is: %s\n", bb);
字符指针作函数参数
把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。
函数的形参和实参可以分别用字符数组名或字符指针变量
main函数:
/**
* 用函数调用实现字符串的复制
* 定义一个函数copy_string用来实现字符串复制的功能,在主函数中调用此函数,
* 函数的形参和实参可以分别用字符数组名或字符指针变量。
* */
// 用字符数组名做形参
void copy_string(char from[], char to[]);
char a1[] = "I am a teacher.";
char b1[] = "You are a student.";
printf("string a = %s\nstring b = %s\n", a1, b1);
printf("\ncopy string a to string b:\n");
copy_string(a1, b1); // 用字符数组名作函数实参
printf("\nstring a = %s\nstring b = %s\n", a1, b1);
// %s格式输出,遇到'\0'结束,如果按照%c输出,则b1未被完全覆盖的内容是可以输出出来的
for (int i = 0; i < sizeof (a1); i++) {
printf("%c", a1[i]);
}
printf("\n");
for (int i = 0; i < sizeof (b1); i++) {
printf("%c", b1[i]);
}
copy_string函数:
// 形参作为字符数组
void copy_string(char from[], char to[]) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i++;
}
to[i] = '\0';
}
main函数:copy_string同上
// 用字符指针变量作实参
void copy_string(char from[], char to[]);
char a2[] = "I am a teacher.";
char b2[] = "You are a student.";
char *from = a2, *to = b2;
printf("string a = %s b = %s\n", a2, b2);
printf("copy string a to string b:");
copy_string(from, to); // 实参为字符指针变量
printf("\nstring a = %s b = %s\n", a2, b2);
main函数:
// 用字符指针变量作形参和实参
void copy_string_p(char *from, char *to);
char *a3 = "I am a teacher."; // a3是char *型指针变量
char b3[] = "You are a student."; // b是字符数组
char *p = b3; // 使指针变量p指向b数组首元素
printf("string a = %s b = %s\n", a3, b3);
printf("copy string a to string b:");
copy_string_p(a3, p); // 调用copy_string_p函数,实参为指针变量
printf("\nstring a = %s b = %s\n", a3, b3);
copy_string_p函数
//定义函数,形参为字符指针变量
void copy_string_p(char *from, char *to) {
for (; *from != '\0'; from++, to++) {
*to = *from;
}
*to = '\0';
}
使用字符指针变量和字符数组的比较
用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混为一谈,主要有以下几点:
- 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1各字符的地址),绝不是将字符串放到字符指针变量中
- 赋值方式。可以对字符指针变量赋值,但不能对数组名赋值。
- 初始化的含义。
- 存储单元的内容。编译时为字符数组分配若干存储单元,以存放个元素的值,而对字符指针变量,只分配一个存储单元
- 指针变量的值是可以改变的,而字符数组名代表一个固定的值(数组首元素的地址),不能改变
- 字符数组中各元素的值是可以改变的(可以对他们再赋值),但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对它们再赋值)
- 引用数组元素。字符数组:下标法,地址法
- 用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串
- 指针是什么
- 指针变量
- 通过指针引用数组
- 通过指针引用字符串
- 指向函数的指针
- 返回指针值的函数
- 指针数组和多重指针
- 动态内存分配与指向它的指针变量
- 有关指针的小结