C sizeof(&;array)返回什么?

C sizeof(&;array)返回什么?,c,string,pointers,sizeof,C,String,Pointers,Sizeof,问题如下: 我知道str2本身就是数组str2中第一个元素的地址。当str2是sizeof的参数时,它返回整个数组str2的大小 此外,&str2也是arrstr2中第一个元素的地址,但类型不同(char(*)[N]==指向数组的指针)。但是&str2是sizeof的参数时,它是如何工作的呢?&str2是一个指针。因此,您只看到平台上指针的大小。str2的类型为char[10](即char`的数组10) &str2的类型为char(*)[10](即指向char的数组10) 因此,当str声明为c

问题如下:


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


此外,
&str2
也是arr
str2
中第一个元素的地址,但类型不同(
char(*)[N]
==指向数组的指针)。但是
&str2
sizeof
的参数时,它是如何工作的呢?

&str2
是一个指针。因此,您只看到平台上指针的大小。

str2
的类型为
char[10]
(即
char`的数组
10)

&str2
的类型为
char(*)[10]
(即指向
char
的数组
10

因此,当
str
声明为
char-str[10]
时,
sizeof(&str2)
产生指针类型的对象的大小
char(*)[10]

str
之间的差异? 读取运算符:

6.5.3.4操作员的大小,1125:
对数组类型应用
sizeof
运算符时,结果是数组中的总字节数

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

此外,
&str2
也是arr
str2
中第一个元素的地址

No,value-wise
&str2
str
都是相同的,但是在语义上都是不同的。一个是由10个字符组成的数组的地址,另一个是一个字符的地址

你在自己的例子中看到的他们之间的一个差异不是(@ouah在回答中解释了这一点)

  • str的类型是
    char[10]
  • &str
    的类型是
    char(*)[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));
}  
A

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

根据指针算术的规则,当您向指针变量添加1时,它开始指向其自身类型的下一个元素。这就是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));
}  

产量

str2 gives  0xbf587046 
*(str2)     H 
*(&str2)    0xbf587046 
**(&str2)   H 
这意味着
*(&str2)==str2
,值是地址。因此
*(str2)=**(&str2)
值为
H

编辑:上面我显示了
&str
str
之间的区别,其中
str
char[10]类型的数组。

char*str
char-str[]
之间的区别以及两者在内存中的存储方式 假设我们有两个声明,如下所示:

char *str1 = "hello";   
char str2[] = "hello";  
在上述声明中,str1
是指向
char
的指针,该指针指向一个常量字符串文字(通过在
“hello”
字符串中保持第一个char
h
的地址)

C中的字符串是
char[N]
(数组)类型,这就是
sizeof(“hello”)
给出6的原因,因为
“hello”
字符串是6个字符长的数组(包括
\0
nul,字符串终止,hello的类型是
char[6]

在内存中,您的
“hello”
字符串存储如下:

 str1         23   24   25   26   27   28
+----+      +----+----+----+----+----+----+
| 23 |      | h  | e  |  l | l  | o  | \0 |    
+----+      +----+----+----+----+----+----+
   +-----------▲

here the address of the hello string is the first address = 23.  
str1: is a pointer capable of storing an address. 
"hello" consists of 6 chars
char*str1=“你好”
基本上存储一个字符串的地址hello到指针变量
str1
,如上图所示

注意:如果需要,可以将str1更改为指向其他字符串。但是您不能修改
hello
字符串。例如,以下代码是有效的:

 char* str1 = "hello";  // str1 points to hello  str1-->"hello"
 str1 = "world";  //Now, str1 points to world  str1-->"world"
现在
str1
指向另一个常量字符串世界

 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
指向常量字符串,因此您不能通过访问/索引内存位置来修改字符串,例如
str1[i]=“A”
;将是非法的,因为您是在只读内存上写的,并且在运行时它的行为是未定义的(尽管没有编译错误,因为它在语法上是正确的)

同样,因为str1是一个指针,所以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;
}  

所以,要分配一个新字符串,我只需分配一个新字符串的地址。但是我不能调用
strcpy()
,它将尝试在只读内存位置上写入,这是非法的

在第二个声明中,
char str2[]=“hello”
str2[]
是以
\0
结尾的字符(或字符串)数组,但不是指针。请注意,因为在这个声明中,size不是默认的size,所以我们看到常量字符串“hello”的大小是6。
str2
的类型是
char[6]

当我们做
char str2[]=“hello”将创建一个字符数组,并将hello字符串复制到该数组中。因此,str2不仅仅是一个指针,而是一个存储完整字符串的数组

从概念上讲,这就像

       str2:
       103  104  105  106  107  108
      +----+----+----+----+----+----+
      | h  | e  |  l | l  | o  | \0 |    
      +----+----+----+----+----+----+
在这种情况下,最近在您的代码中,您被禁止执行
str2[]=“world” char* str1 = "hello";  // str1 points to hello  str1-->"hello"
 str1 = "world";  //Now, str1 points to world  str1-->"world"
 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. 
#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
       str2:
       103  104  105  106  107  108
      +----+----+----+----+----+----+
      | h  | e  |  l | l  | o  | \0 |    
      +----+----+----+----+----+----+
#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
       strcpy(str2, "world");

       str2:
       103  104  105  106  107  108
      +----+----+----+----+----+----+
      | w  | o  |  r | l  | d  | \0 |    
      +----+----+----+----+----+----+

      Note that when "world" is copied into a same memory space, the addresses of both "world" and "hello"
      string are the same.  
#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