[英]If C can return only one value(int , char etc.) then how does it returns character string literal(array of chars)?
char *returnString()
{
return "hello World";
}
int main()
{
printf("\n %p ", &returnString());
return 0;
}
returnString()
在这里返回什么? 它是否返回'h'
地址?
如果是,那么"hello world"
存储在哪里(堆栈/堆)? 如何查看(打印)它的地址?
char Hello[] = "It's Hello";
char something[] = "something like ";
char *readInput(char str[]) {
char *tempStr = NULL;
if (strcmp(str, "hello") == 0)
return Hello;
tempStr = (char *)malloc((strlen(something)) + (strlen(str)) + 1);
strcpy(tempStr, something);
strcat(tempStr, str);
return tempStr;
}
int main() {
int i;
char *userInput[] = { "hello", "xyz", "hello", "abc" };
char **result = (char **)malloc(sizeof(char *) * (4));
for (i = 0; i < 4; i++) {
result[i] = (char *)malloc(15);
result[i] = readInput(userInput[i]);
}
printf("\n\n");
strcpy(Hello, "String is Changed"); // this should not affect result[0] && result[2]
for (i = 0; i < 4; i++)
printf("\t\t %s", result[i]);
printf("\n");
return 0;
}
应该在第二个程序中进行哪些修改,以便即使在此之后 ---> strcpy(Hello, "String is Changed");
result[0]
和result[2]
不会改变。
语句return "hello World";
返回一个char *
:指向字符串文字"hello World"
的第一个字符的指针。 此字符串文字存储为 12 个char
的空终止数组。 它通常与程序的其他常量数据一起存储在内存中。
尝试修改此数组会调用未定义的行为。 它应该被视为const
并通过const char *
处理。 将此函数定义为更安全
const char *returnString(void) {
return "hello World";
}
此外,您不应在printf
语句中的函数调用上使用&
。 它应该是:
int main(void) {
printf("\n%p\n", (void*)returnString());
return 0;
}
关于您的第二个问题,您应该在Hello
返回字符串的副本。 使用这个简单的方法:
if (strcmp(str, "hello") == 0)
return strdup(Hello);
strdup()
未在 C 标准中定义,但在 Posix 标准中指定。 如果它在您的系统中不可用,则可以将其定义为:
char *strdup(const char *s) {
char *p = malloc(strlen(s) + 1);
if (p) strcpy(p, s);
return p;
}
分配字符串的位置取决于您如何编写它。 这些都返回字符串,但方式不同:
const char *a()
{
return "hello, world";
}
char *b()
{
return strdup("hello, world");
}
char *c()
{
char buf[16];
strcpy(buf, "hello, world");
return buf; /* wrong */
}
char *d()
{
static char buf[16];
strcpy(buf, "hello, world");
return buf;
}
void e(char *buf)
{
strcpy(buf, "hello, world");
}
a
返回一个字符串文字。 它存储在只读存储器中,不能更改。
b
返回分配在堆上的字符串。 必须通过调用free
来释放它。
c
返回分配在堆栈上的字符串。 但是,这是错误的,因为您不能返回指向局部变量的指针,在本例中为buf
。 当到达右括号时,被引用的对象不再存在。
d
提供了对c
的改进。 当变量声明为static
,它(在许多编译器上)存储在.bss
段中。 然而,这不是更正,因为它不是线程安全的。
e
不是通过返回机制返回一个字符串,而是通过填写一个地址。 不推荐使用此代码,因为可能会发生缓冲区溢出。 调用者可以在堆栈或堆上分配e
的参数。 只要有足够的空间来执行复制,它就会工作。
e
改进版本:
/* n is the size of buf, in chars */
void eImproved(char *buf, size_t n)
{
if (n > sizeof "hello, world") /* enough room in buf for copy */
strcpy(buf, "hello, world");
else
buf[0] = '\0'; /* if not enough room, make buf empty */
}
如果要打印地址,请在 printf 中使用%p
:
printf("%p", a());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.