Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C &;数组==数组,那么结构呢?_C_Arrays_Pointers_Reference - Fatal编程技术网

C &;数组==数组,那么结构呢?

C &;数组==数组,那么结构呢?,c,arrays,pointers,reference,C,Arrays,Pointers,Reference,我刚开始搞结构和指针 这是我的。h: #ifndef struct_struct_h #include <string.h> #define struct_struct_h #endif int count=0; typedef struct { int num; double balance; const char * name; struct Account * acnt; } Account; Account* a = N

我刚开始搞结构和指针

这是我的。h:

#ifndef struct_struct_h
#include <string.h>
#define struct_struct_h



#endif


int count=0;

typedef struct
{
    int num;
    double balance;
    const char * name;
    struct Account * acnt;
    
} Account;

Account* a = NULL;

Account* new_account(const char * n)
{
    Account *a1 = malloc(sizeof(Account));
    
    a1->num=++count;
    a1->name = n;
    return a1;
}
\ifndef struct\u struct\h
#包括
#定义结构
#恩迪夫
整数计数=0;
类型定义结构
{
int-num;
双平衡;
常量字符*名称;
结构帐户*acnt;
}账户;
账户*a=NULL;
账户*新账户(const char*n)
{
账户*a1=malloc(账户规模);
a1->num=++计数;
a1->name=n;
返回a1;
}
这是我的主要观点。c:

#include <stdio.h>
#include <string.h>
#include "struct.h"



int main(int argc, const char * argv[])
{

    // insert code here...
    Account* accounts[2];
    
    for(int i=0; i<2; i++)
    {
        accounts[i] = (i==0 ? new_account("David") : new_account("Toto") );
    }
    printf("Accounts array address is %i\n",&accounts);
    
    for(int i=0; i<2;i++)
    {
        printf("Account n°%i is owned by %s \n, its address is %i\n",accounts[i]->num,accounts[i]->name,&accounts[i]);
    }
    printf("There are %i accounts.\n",count);
    
    return 0;
}
#包括
#包括
#包括“struct.h”
int main(int argc,const char*argv[]
{
//在这里插入代码。。。
账户*账户[2];
对于(int i=0;iname,&accounts[i]);
}
printf(“有%i个帐户。\n”,计数);
返回0;
}
如果我用accounts替换&accounts,则得到相同的结果:@array,或者是&accounts[0],就可以了

帐户数组地址为1606416480

如果我将&accounts替换为*accounts,我会得到以下结果:

帐户数组地址为1063600

第二个输出是:

1号账户归David所有 ,地址为1606416480

2号账户归Toto所有 ,其地址为1606416488

实际上,这些是帐户中包含的帐户指针的@,它们在内存中每个@占8B

如果我将&accounts[I]替换为accounts[I],那么通过*accounts[I]我得到:

1号账户归David所有 ,地址为1063600

2号账户为Toto所有,地址为1063632

1号账户归David所有 ,地址是3874

2号账户归Toto所有 ,地址是3880

在第一种情况下,我有2个指针,在第二种情况下,我有2个*指针


*STRUCT和STRUCT是不同的,为什么?

数组在内部表示为连续的内存范围。在数据块的最开始处,放置了数组的第一个元素

例如,如果有一个数组的命名方式与问题
accounts
中的命名方式相同,那么数组的地址和数组的第一个元素的地址具有相同的值

如果考虑你的例子,那么你就有了

Account * accounts[2];
表达式中极少数例外的数组(例如在sizeof运算符中使用数组)被转换为指向其第一个元素的指针

因此表达式
accounts
具有类型
Account**
和等式

accounts == &accounts[0]
计算结果为true

表达式
&帐户
具有相同的值,因为它是扩展数据块的地址,但类型不同。它的类型是

Account * ( * )[2]
这是如果你写的例子

Account *( *p )[2] = accounts;

printf( "*p = %zu\n", sizeof( *p ) ); 
然后输出将等于16,因为在运行自己代码的环境中,指针的大小等于8,数组由两个指针元素组成

你可以不写条件

&accounts == accounts
因为操作数有不同的类型。但是如果你写

( void *)&accounts == ( void * ) accounts 
然后,该条件的计算结果为true

所以表达式的值

&帐户
帐户
&帐户[0]
彼此相等,是数组占用的内存块的地址

对于结构,则结构的地址等于其第一个成员的地址。但是,结构类型的对象的名称不会隐式转换为指向其第一个成员的指针

如果我将&accounts[I]替换为accounts[I],那么通过*accounts[I]我得到:

&accounts[i]
给出数组元素的地址。所以你会得到价值观

Account n°1 is owned by David , its address is 1606416480

Account n°2 is owned by Toto , its address is 1606416488
两个值之间的差值等于
8
,即表达式
sizeof(Account*)

accounts[i]
给出存储在数组元素中的值。它们是结构类型的每个对象的动态alllocated内存地址

*账户[i]是结构类型的对象。由于printf调用中的格式说明符与作为参数传递的对象不对应,因此函数行为未定义


考虑到要打印指针,您必须使用格式说明符
%p

TL/DR版本:

数组是特殊的,在大多数情况下,数组表达式被视为指向数组第一个元素的指针
a
&a
将产生相同的值(数组
a
的第一个元素的地址),尽管表达式的类型不同

struct
类型(或任何其他聚合类型)并非如此

大卫·福斯特·华莱士版本:

除非它是
sizeof
或一元
&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则类型为“
N
-element array of
T
”的表达式将转换(“衰减”)为类型为“pointer to
T
”的表达式,表达式的值将是数组中第一个元素的地址

为什么会这样

首先,让我们看看数组在内存中是如何表示的。根据声明

T a[N];
然后你会得到这样的结果:

   +---+
a: |   | a[0]
   +---+
   |   | a[1]
   +---+
    ...
   +---+
   |   | a[N-1]
   +---+
存储是为数组元素而不是其他元素预留的;没有存储任何元数据或指向数组第一个元素的任何指针。关键是,除了数组元素之外,没有对象
arr
(换句话说,对象
arr
就是数组元素)

但是数组下标操作
a[i]
被定义为
*(a+i)
;也就是说,给定一个地址
a
,我们从该地址偏移
i
元素(不是字节!)并取消引用结果

但是
a
是一个数组,而不是指针,那么它怎么工作呢

类似于此-除非它是
sizeof
或一元
&
运算符的操作数,或者是
printf( "a = %p\n", (void *) a ); // *always* use `%p` to print pointer values

  Expression        Type        "Decays" to        Value
  ----------        ----        -----------        -----
           a        T [N]       T *                Address of first element 
          &a        T (*)[N]    n/a                Same value as above, different type
          *a        T           n/a                Value of first element
        a[i]        T           n/a                Value of 
i
'th element &a[i] T * n/a Address of
i
'th element sizeof a size_t n/a Number of bytes in array sizeof *a size_t n/a Number of bytes in single element sizeof a[i] size_t n/a Same as above sizeof &a size_t n/a Number of bytes in pointer to array sizeof &a[i] size_t n/a Number of bytes in pointer to single element
T a[N];
T *p = a;
T (*ap)[N] = &a;

printf( " p = %p,  p + 1 = %p\n", (void *) p, (void *) p + 1 );
printf( "ap = %p, ap + 1 = %p\n", (void *) ap, (void *) ap + 1 );