sizeof(&array)返回什么?

下面的问题: 一个数组的地址是如何等于它在C中的值?

#include <stdio.h> #define N 10 char str2[N]={"Hello"}; int main(){ printf("sizeof(str2): %d bytes\n", sizeof(str2)); printf("sizeof(&str2): %d bytes\n", sizeof(&str2)); return 0; } 

输出:

 sizeof(str2): 10 bytes sizeof(&str2): 4 bytes 

我知道str2本身就是str2中第一个元素的地址。 而当str2sizeof的参数时,它将返回整个数组str2的大小。

另外, &str2也是arr str2第一个元素的地址,但是来自于不同types( char (*)[N] ==指向数组的指针)。 但是当&str2是一个sizeof的参数时, &str2如何performance的?

&str2是一个指针。 所以你只是看到你的平台上的指针的大小。

str被声明为char str[10]时, &strstr之间的区别?

阅读sizeof运营商:

6.5.3.4运营商的规模,1125:
sizeof运算符应用于数组types时,结果是数组中的总字节数。

因此,根据您的声明, sizeof(str2)给出了10个字节的完整数组大小(因为N定义为10,char大小为1个字节)。
而在expression式sizeof(&str2)&str2是您的系统中4个字节的地址数组和地址的大小。 (在一些系统中,地址大小可能是8字节,例如64位)。

另外, &str2也是arr str2第一个元素的地址?

,value-wise &str2str都是相同的,但是在语义上都是不同的 。 一个是10个字符的数组的地址,而另一个是char的地址。

你在自己的例子中看到的一个区别是它们是如何不同的(在这个答案中解释了@ouah)。

  • strtypes是char[10]
  • types的&strchar(*)[10]

第二:下图将帮助您观察其他差异。

 for declaration: #define N 10 char str2[N] = {"Hello"}; str2 Array in memory is something like: ---------------------------------------- str +----+----+----+----+----+----+----+----+----+----++----+ |'H' |'e' |'l' |'l' |'o' |'\0'|'\0'|'\0'|'\0'|'\0'|| '@'| +----+----+----+----+----+----+----+----+----+----++----+ 201 202 203 204 205 206 207 208 209 210 211 ▲ ▲ ▲ ▲ | | | | |(str2) (str2 + 1) | | | |-----------------------------------------------------| |201 | | | | | (&str2) = 201 (&str2 + 1) = 211 * assuming str address start from 201 * str[N] is 10 char long 201-210, partially initialized * at uninitialized position, str2[i] = '\0' * location 211 is unallocated, having garbage value, access to this location is illegal-Undefined Behavior 

对于上面的图你可以写一个代码:

 #include <stdio.h> #define N 10 int main(){ char str2[N]={"Hello"}; printf("\n %p, %p\n",str2, str2+1); printf("\n %p, %p\n",(&str2), (&str2+1)); } 

输出:

  0xbf67e142, 0xbf67e143 0xbf67e142, 0xbf67e14c 

键盘的链接:

注意第一行输出地址差异是一个字节,但是第二行差异是10字节,因为它的数组指针(如上图所示)。

根据指针math规则,当你给指针variables加1时,它开始指向它自己types的下一个元素,这就是10字节差异的原因,因为&str2是数组地址。

第三个区别:

通过做*str2你可以访问第一个元素。 *(&str2)不会给你第一个元素,而是第一个元素的地址。

一个例子将在这里帮助:

 #include <stdio.h> #define N 10 int main(){ char str2[N]={"Hello"}; printf("\n%p %c, %p %c\n",str2, *(str2), *(&str2), **(&str2)); } 

输出:

 0xbf587046 H, 0xbf587046 H 

键盘链接

在输出

 str2 gives 0xbf587046 *(str2) H *(&str2) 0xbf587046 **(&str2) H 

这意味着*(&str2) == str2和值是地址。 因此*(str2) = **(&str2)值是H

编辑:上面我显示了&strstr之间的区别,其中strchar[10]types的数组。

char *strchar str[]之间的区别以及两者如何存储在内存中

假设我们有两个声明如下:

 char *str1 = "hello"; char str2[] = "hello"; 

在上面的声明中, str1是一个指向char的指针,指向一个常量string(通过在"hello"string中保存第一个char h地址)。

C中的一个string是char[N] (array)types,这就是为什么sizeof("hello")给出6的原因,因为"hello"string是6个字符长数组(包括\0 nul,string终止,hellotypes是char[6] )。

在内存中, "hello"string的存储方式如下所示:

  str1 23 24 25 26 27 28 +----+ +----+----+----+----+----+----+ | 23 | | h | e | l | l | o | \0 | +----+ +----+----+----+----+----+----+ +-----------▲ here address of hello string is first address = 23. str1: is pointer capable to store address. "hello" consists of 6 chars 

char* str1 = "hello"; 基本上将stringhello的地址存储到指针variablesstr1 ,如上图所示。

注意:如果你最近想在你的代码中改变str1来指向另一个string。 但是你不能修改hellostring。 例如下面的代码是有效的:

  char* str1 = "hello"; // str1 points to hello str1-->"hello" str1 = "world"; //Now, str1 points to world str1-->"world" 

现在str1指向其他常量string的世界。

  str1 93 94 95 96 97 98 +----+ +----+----+----+----+----+----+ | 93 | | w | o | r | l | d | \0 | +----+ +----+----+----+----+----+----+ +-----------▲ here address of world string is first address = 93. str1: value change to point string world. 

重要的是要注意: str1指向常量string,因此您不能通过访问/索引内存位置来修改string,例如str1[i] = 'A' ; 将是非法的,因为你正在写只读内存 ,这是行为未定义在运行时(虽然没有编译错误,因为在语法上是正确的)。

再次,因为str1是一个指针sizeof(str1)将在同一台机器上给4。

我的下面的代码和它的运行:

 #include <stdio.h> int main(){ char* str1="Hello"; printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1)); str1 = "world"; printf("\nstr1: %s, address: %p, sizeof(str1): %u", str1, str1, sizeof(str1)); return 1; } 

输出:

 str1: Hello, address: 0x80485e8, sizeof(str1): 4 str1: world, address: 0x8048619, sizeof(str1): 4 

键盘链接

所以,分配新的string我只是分配新的string的地址。 但是我不能调用strcpy() ,它会尝试写入只读内存位置,这是非法的。

在第二个声明char str2[] = "hello";str2[]是字符(或string)的终止数组,但是不是指针。 注意,因为在这个声明中没有给出大小的默认大小,我们将那个常量string“hello”的大小定义为6. str2types是char[6]

当我们做char str2[] = "hello"; 一个char数组创build和hellostring将被复制到该数组所以str2不是简单的指针,而是一个数组存储完整的string。

它在概念上就像。

  str2: 103 104 105 106 107 108 +----+----+----+----+----+----+ | h | e | l | l | o | \0 | +----+----+----+----+----+----+ 

在这种情况下,最近在你的代码中,你不允许做str2[] = "world";str2 = "world"感染它将是编译时间错误。

示例代码:

 #include<stdio.h> int main(){ char str2[] = "hello"; str2[] = "world"; str2 = "world"; return 1; } 

编译错误:

 In function 'main': Line 4: error: expected expression before ']' token Line 5: error: incompatible types in assignment 

代码链接

在这个数组str2不是常量的地方,我们可以修改它的内容,比如str2[2] = 'A'是完全有效的。 我们也可以调用strcpy来改变内容(并且地址空间不会改变)

  strcpy(str2, "world"); str2: 103 104 105 106 107 108 +----+----+----+----+----+----+ | w | o | r | l | d | \0 | +----+----+----+----+----+----+ Note world coped into same memory space, address of world and hello string is name. 

代码示例:

 #include<stdio.h> int main(){ char str2[] = "hello"; printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); str2[2] = 'A'; printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); strcpy(str2, "world"); printf("\nstr2: %s, address: %p, sizeof(str2): %u", str2, str2, sizeof(str2)); return 1; } 

输出:

 str2: hello, address: 0xbf58d056, sizeof(str2): 6 str2: heAlo, address: 0xbf58d056, sizeof(str2): 6 str2: world, address: 0xbf58d056, sizeof(str2): 6 

键盘链接

注意:string值在相同的地址空间上是不同的。 sizeof(str2) = 6完全可以从旧的答案中理解,即字节数组的大小。

阅读有关2维数组读取类似的描述: char* str[]char str[][]之间的区别,以及如何在内存中存储?

str2的types是char [10] (即char [10]数组10 of

&str2的types是char (*)[10] (即指向char数组10的指针)。

所以sizeof (&str2)产生一个指针typeschar (*)[10]的对象的大小char (*)[10]