“abc”之间的区别是什么和{“abc”}。 [英] Whats the difference between "abc" and {"abc"} in C?

查看:197
本文介绍了“abc”之间的区别是什么和{“abc”}。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C语言中(我想这也适用于C ++),

In C specifically (i suppose this also applies to C++), what is the difference between

char str[4] = "abc";
char *cstr = {"abc"};

当我尝试将我的abc传递到接受char **的函数时会出现问题

Problems arise when i try and pass my "abc" into a function that accepts char**

void f(char** s)
{
  fprintf(stderr, "%s", *s);
}

执行以下操作会产生编译器错误。如果转换为字符**(以使编译器快乐)程序seg故障。

Doing the following yields a compiler error. If cast to char** (to make compiler happy) program seg faults.

f(&str);

但以下工作正常

f(&cstr[0]);


推荐答案

这是一个指针和数组如何<

This is an example of how pointers and arrays are not equivalent in C. In particular: the rule that arrays decay to pointers is not applied recursively

这意味着,在数组中, 数组可以用作指针,但指针到数组不能用作指针到指针。这是你在这里经历的。这就是为什么当你不明确地将char和char转换为char **时,编译器会报告不匹配的类型。这应该是你的第一个线索,有什么不对。

This means that an array can be used as a pointer, but a pointer-to-array cannot be used as a pointer-to-pointer. This is what you are experiencing here. This is why the compiler complains about mismatched types when you don't cast &str explicitly to char**. That should be your first clue that something is wrong.

这导致segfault的原因是:数组自动衰减到指针的方式是转成其第一个元素的地址。指向数组的指针同样是指向数组第一个元素的地址的指针。因此,指向数组的指针和作为指针的数组是相同的。换句话说,当作为指针传递时,str具有与& str相同的值。因此,如果你尝试将&str作为指针指针,它不工作,因为它只是一个(单级)指针。

The reason that this causes a segfault is this: The way that an array automatically decays to a pointer is by turning into the address of its first element. A pointer to an array is likewise a pointer to the address of the array's first element. So a pointer-to-array and array-as-pointer are the same thing. In other words str, when passed as a pointer, has a value identical to &str. So if you try to make &str into a pointer-to-pointer, it doesn't work, since is just a (single-level) pointer.

例如,

void f(char** pp);
void g(char* p);

char[] str = "abcd"; // Lets say this is allocated at address 0x1234
g(str); // Value of p in g is 0x1234 (by automatic conversion of char[4] to char*)

char* p_str = &str; // Value of p_str is 0x1234
g(p_str); // Value of p in g is again 0x1234 

f(str);  // Illegal, no conversion of char[] to char** (obvious)
f(p_str); // Illegal, no conversion of char* to char** (obvious)
f(&str); // Illegal, no conversion of char*[4] to char** (less obvious)

f((char**)p_str); // Ok, now you're overriding the typecheck

但是最后调用 f((char **)p_str),f中的pp值仍然为0x1234,因为您尚未修改p_str的值,检查员的投诉。这意味着* pp将是'a',而不是指向包含'a'的地址的指针。这就是为什么当f试图执行** pp。

But after that last call to f((char**)p_str), the value of pp in f is still going to be 0x1234 because you haven't modified the value of p_str, you've only suppressed the type-checker's complaint. This means that *pp is going to be 'a', not a pointer to the address that contains 'a'. And that's why you get a segfault when f tries to execute **pp.

这篇关于“abc”之间的区别是什么和{“abc”}。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆