有以下程序
#include <stdio.h>
#include <string.h>
void fun(char *s) {
char a[10];
strcpy(a, "STRING");
s = a;
}
main() {
char *p = "PROGRAM";
fun(p);
printf("%s\n", p);
}
程序运行后的输出结果是(此处□代表空格)?
二天
#include<iostream>
using namespace std;
void test(char *p)
{p="B";}int main()
{
char p[10]="A";
test(p);
cout<<p;}为什么输出的不是B
由于函数声明为void test(char *p); 这种是传值参数,当进行test(p);函数调用时,实参p把它的值,也就是字符串常量"A"的首地址赋值给了形参p,但注意这是形参p是实参p的一个副本,而不是实参p的引用。当执行p="B";时,形参p的值就被改写为字符串常量"B"的首地址,但实参p和形参p是两个独立的变量,因此对形参p的修改不会影响到实参p,所以实参p的值仍然是字符串常量"A"的首地址。由于形参p的作用域是在test函数内,所以当test调用结束,形参p也会被释放掉。当执行cout<<p;是输出的是指向字符数组的首地址指针的值,由于test函数没有改变字符数组的值,所以输出A而不是B。如果你想输出B的话,可以把函数改为
void test(char *&p)
{p="B";}
这是用引用的方式传值。
#include<stdio.h> #include<string.h> void fun(char *s)//s是main中p的拷贝,s和p都指向“hello”{ char a[10]; strcpy(a, "STRING"); s = a; //只能改变s,无法改变main中p的指向 printf("%s\n", s); }//子函数结束后,s消失,p并没有改变int main() { char *p = "hello"; char a[10] = "hello"; fun(p); printf("%s\n", p); //strcpy(p, "STRING"); //无法修改*p = "hello"的内容 strcpy(a, "STRING"); //字符数组可以修改 printf("%s\n", a); }
#include <stdio.h>
#include <string.h>
void fun(char **s) { // 二级指针,接收p的地址
char a[10];
strcpy(a, "STRING");
*s = a; // 修改*s(即main中的p),让p指向局部数组a
}
int main() {
char *p = "PROGRAM";
fun(&p); // 传递p的地址,使fun能修改p
printf("%s\n", p); // 理论上应输出"STRING",但a是局部数组,函数结束后内存回收,实际可能为未定义行为
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 包含malloc/free
void fun(char **s) {
char *a = (char *)malloc(10); // 动态分配内存,生命周期由程序员控制
if (a != NULL) { // 检查内存分配是否成功
strcpy(a, "STRING");
*s = a; // 让p指向动态分配的内存
}
}
int main() {
char *p = "PROGRAM";
fun(&p);
printf("%s\n", p); // 输出"STRING"(内存有效)
free(p); // 释放动态分配的内存,避免内存泄漏
return 0;
}