这是一个演示从func
获取字符串值的示例程序我面临着第二种方式的问题。 有什么解决方法吗?
/*
* main.c
*
* Created on: Sep 6, 2014
* Author: Murtaza
*/
#include<stdio.h>
#include<stdlib.h>
char* someFunc1();
void someFunc2(char* str);
void firstApproach();
void secondApproach();
int main()
{
firstApproach();
printf("\n");
secondApproach();
return 0;
}
char* someFunc1()
{
char *str = (char*)malloc(sizeof(char)*10);
str = "HELLO";
return str;
}
void someFunc2(char* str)
{
str = "Hello";
}
void secondApproach()
{
char *str = (char*)malloc(sizeof(char)*10);
someFunc2(str);
printf(str);
printf("heythere");
}
void firstApproach()
{
char *str;
str=someFunc1();
printf(str);
printf("wassup");
}
请告诉我为什么第二种方法不起作用。 谢谢! 我的输出是:
HELLOwassup
h>heythere
我的预期输出应为
HELLOwassup
Helloheythere
答案 0 :(得分:2)
void someFunc2(char* str)
{
str="Hello"; //-----the variable str is local to this function, thus it goes out of scope as
// soon as the function returns
}
void secondApproach()
{
char *str=(char*)malloc(sizeof(char)*10);
someFunc2(str);
printf(str); // -------------- here the value inside str is some garbage value.
printf("heythere");
}
CORRECTION :
void someFunc2(char **str )
{
*str = "hello";
}
void secondApproach()
{
char *str=(char*)malloc(sizeof(char)*10);
someFunc2(&str); // pass the address of the string
printf("%s", str);
printf("heythere");
}
答案 1 :(得分:1)
让我们仔细看看someFunc2
:
void someFunc2(char* str)
{
/* str is a copy of the pointer that was passed in from secondApproach(). */
str = "Hello";
}
在这里,您按值传递指针。因此,str
中的someFunc2
是从str
传入的原始指针secondApproach()
的副本。 someFunc2
告诉复制指针指向其他地方,但它只留下原始的str
指针。解决方法是传入str
指针的地址,然后告诉someFunc2
修改该地址的指针以指向"hello"
。
void secondApproach()
{
char* str = (char*) malloc(sizeof(char) * 10);
someFunc2(&str); // Pass in the address of str.
printf("%s", str);
printf("heythere");
}
void someFunc2(char** str)
{
*str = "hello";
}
答案 2 :(得分:0)
当您在引号之间编写字符串并直接使用它时:
char * - &gt;它在内存中的可变位置创建,并将其地址提供给它所分配的指针变量。只要引用它的变量不是NULL,它仍然在内存中。
参数 - &gt;它被创建为char*
并传递给函数(并在那里作为char *处理),然后自动从内存中释放(即你无法访问或引用它)..
因此,字符串实际上是可变的唯一情况是当你将它分配给char[]
时,它会在只读内存中创建并复制到堆栈中。(堆栈上的副本是什么char[]
变量将指向)
如果你想一段时间,你会发现这是动态记忆的好处之一:你可以创建一个{b} 可变的char*
,因为它只是一个指针,你不需要指定它将指向的字符串的大小。所以你可以看到这将是多么有用..
另外,值得注意的是功能:
如果传递一个字符串,函数本身中的变量将被视为char指针,并且很可能会尝试修改它,如果只读它会引发分段错误。所以函数假设你知道你在做什么..
如果您希望函数能够直接修改字符串(即string =“somestring”),则将指针传递给实际字符串,否则修改将仅对函数本地化。那是因为字符串是“指向char的指针”,所以函数不能整体修改字符串。但这也意味着函数可以单独修改字符串的字符(显然,因为它有一个字符指针:字符串)。但是,如果传递一个字符串指针(char**
),该函数可以直接修改字符串(*string = "whatever"
),也可以单独修改字符(*string[1] = 'C'
)。您需要哪种选择完全取决于功能的目的..
现在,根据您的具体示例,您可以执行两个中的一个..
void someFunc2(char** str)
{
*str = "Hello";
}
void someFunc2(char* str)
{
char *k = "Hello";
for(int i = 0; i < 5; ++i)
str[i] = k[i];
}
这是C中最具争议和最高级的主题之一。无论您正在做什么类型的C编程,您都必须了解这些核心概念。