一直在想,用[]或*声明变量之间的区别是什么?我看待它的方式:
char *str = new char[100]; char str2[] = "Hi world!";
..应该是主要的区别,虽然我不确定你是否可以做类似的事情
char *str = "Hi all";
..因为指针应该引用一个静态成员,我不知道它是否可以?
无论如何,真正困扰我的是知道以下两者之间的区别:
void upperCaseString(char *_str) {}; void upperCaseString(char _str[]) {};
所以,如果有人能告诉我差异,我将不胜感激吗?我有一种预感,除了一些特殊情况外,两者都可以编译得相同吗?
泰
让我们看看它(对于以下内容,注意char const
并const char
在C++中是相同的):
"hello"
是一个由6个const字符组成的数组:char const[6]
.作为每个数组,它可以隐式转换为指向其第一个元素的指针:char const * s = "hello";
为了与C代码兼容,C++允许另外一个转换,否则会形成错误:char * s = "hello";
它会删除const!.这是一个例外,允许编译C-ish代码,但不推荐使用它来char *
指向字符串文字.那么我们有什么用char * s = "foo";
?
"foo"
- > array-to-pointer
- > char const*
- > qualification-conversion
- > char *
.字符串文字是只读的,不会在堆栈上分配.你可以自由地指向它们,并从函数返回那个,而不会崩溃:).
现在,是什么char s[] = "hello";
?这是一个整体的其他事情.这将创建一个字符数组,并用String填充它"hello"
.字面意思没有指出.而是将其复制到字符数组中.并且数组在堆栈上创建.您无法从函数中有效地返回指向它的指针.
如何使函数接受数组作为参数?您只需将参数声明为数组:
void accept_array(char foo[]);
但你省略了大小.实际上,任何大小都会这样做,因为它只是被忽略:标准说,以这种方式声明的参数将被转换为相同的
void accept_array(char * foo);
替换char
任何类型,包括数组本身:
void accept_array(char foo[][10]);
接受一个二维数组,其最后一个维度的大小为10.多维数组的第一个元素是它的下一个维度的第一个子数组!现在,让我们改变它.它将再次指向其第一个元素.所以,实际上它会接受一个指向10个字符数组的指针:(删除[]
头部,然后只需指向你在脑中看到的类型):
void accept_array(char (*foo)[10]);
当数组隐式转换为指向其第一个元素的指针时,您只需传递一个二维数组(其最后一个维度大小为10),它就可以工作.实际上,任何 n维数组的情况都是如此,包括特殊情况n = 1
;
void upperCaseString(char *_str) {};
和
void upperCaseString(char _str[]) {};
是相同的,因为第一个只是一个指向char的指针.但请注意,如果您想将String-literal传递给它(假设它不会更改其参数),那么您应该将参数更改为char const* _str
不要弃用的东西.
三个不同的声明让指针指向不同的内存段:
char* str = new char[100];
让str指向堆.
char str2[] = "Hi world!";
将字符串放在堆栈上.
char* str3 = "Hi world!";
指向数据段.
这两个声明
void upperCaseString(char *_str) {}; void upperCaseString(char _str[]) {};
如果相同,当您尝试在同一范围内声明它们时,编译器会抱怨已经有一个正文的函数.