【问题标题】:C - Dynamic MemoryC - 动态内存
【发布时间】:2014-07-18 15:18:23
【问题描述】:

我目前正在学习动态记忆,但我的书并不清楚这一点。为什么dynArray 的声明没有 [ ] 括号,不使用 malloc 时用于数组声明。为什么在声明时不需要[ ],但在循环中需要。

int * dynArray;
dynArray = malloc(sizeof(int)*5);
srand ( time(NULL) );

for(i=0; i<=myInt; i++){
    dynArray[i] = rand()%100;
  }

【问题讨论】:

标签: c memory dynamic


【解决方案1】:

循环中不需要;指针可以作为数组访问,数组也可以作为指针访问

这是等价的

for(i=0; i<=myInt; i++){
    *(dynArray+i) = rand()%100;
}

【讨论】:

  • 为什么在减速过程中不需要该数组中的项目数?
  • @user3753834 因为它还不是一个“数组”。这是一个指针。然后让它指向一个实际的数组(由malloc() 分配)。数组和指针之间的区别在索引之前不会消失:数组和指针可以被相同地索引。
  • 你的 malloc() 返回一个指向一些内存的指针,其中有 5 个整数的空间。然后,您可以使用数组表示法访问这些元素。
  • @user3753834 您接受了错误的答案。当然,您可以互换使用[]+,但避免使用[] 只会使您的代码难以遵循。没有理智的程序员会选择*(arr+i) 而不是arr[i]
  • @DavidHeffernan 是什么让指针算术比数组表示法更难或更容易遵循?一致性是关键。一些真实的例子livegrep.com/search/linux?q=pointer+arithmetic
【解决方案2】:

区别在于它的地址何时知道。

对于一个简单的int a[5] 数组,编译器知道它在哪里,所以它的地址是常量(或者是相对于堆栈或相对于结构体的,都是一样的)。

OTOH int* a 表示 a 只是一个变量,而不是一个常量,它恰好指向一个或多个 int。正在运行的程序可以自己分配和设置a,由程序员自己知道自己在做什么。

但索引a[i] 在任何一种情况下都是一样的。它将a 作为数组的地址,然后将iint 的大小相加,这就是实际整数的地址。

【讨论】:

    【解决方案3】:

    这定义了一个特定大小的数组:

    int array1[10];
    

    这定义了一个指向整数的指针:

    int * array2;
    

    两个定义都分配了一些内存。第一个分配空间来容纳 10 个整数。第二个分配空间来保存指向整数的指针。

    array1 在表达式中用作右值时,它会退化为指针。所以使用array1 右值相当于取它的地址:&amp;array1。在表达式中,array1array2 右值是等价的:它们充当指向 int 值的指针。不同之处在于您不能将array1 用作左值:您不能分配给它,也不能修改它——因为它不是您可以写入的指针。当然,您当然可以修改array1-acting-as-a-pointer 或array2 指向的值。

    上面的两个定义都给你未初始化的变量:array1 的内容没有定义,array2 的内容也没有定义。因此,例如,在分配值之前取消引用 array2 指针是错误的。

    您可以将array2设置为array1中分配的10个整数区域的地址,那么两者是等价的:

    int array1[10];
    int * array2 = array1;
    array1[0] = 1;
    array2[0] ++; // Increment the first item of the array
    assert(array1[0] == 2);
    

    虽然您当然可以让array2 指向第一个数组中的第二个项目,但您不能更改array1 指向的位置:

    array2 ++; // Increment the pointer so that it points to the second item of the array
    assert(array2 == &array1[1]);
    
    array1 ++; // Triggers a compile-time error diagnostic
    

    来自#include &lt;assert.h&gt;assert 只是一种断言某些事实的方式。如果它们在运行时被证明是错误的,则程序将中止。这也是一种用 C 语言简洁地表达某些事情在程序中的某些点是正确的方式。这比编写 cmets 更好,因为将在运行时的调试版本中为您检查断言。

    【讨论】:

      猜你喜欢
      • 2013-09-30
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-07
      • 2015-06-27
      • 2021-02-28
      • 2015-12-13
      相关资源
      最近更新 更多