如果arr是T类型的数组,那么& arr的效用是什么?

时间:2015-06-18 19:31:49

标签: c arrays pointers

好的,请考虑使用C:

中的一段代码
int main(int argc, char *argv[])
{
     int arr[10];
     arr;     // This has an address to the first element of arr[10] and is of type int *
     &arr;    // Has same value as arr but the type is a pointer to an array of [10] ints. Also pointer arithmetic here would be different as compared to arr.
     int var; //var is a variable and has an address. &&var --> Doing this would be invalid. If so, then what is arr? Why is &arr allowed? 
     return 0;
}

我知道上面两个表达式之间的区别,但是我很难理解为什么这两个表达式具有相同的值?所以我对此有两个问题:

  1. 考虑arr[0]是否具有0x100的任意位置,那么为什么arr&arr具有相同的值?编译器究竟如何处理这两个表达式以及它们将如何在内存中实际实现?
  2. 在C中使用&arr究竟有什么用?由于arr已经是一个地址,为什么&操作员甚至可以使用它?
  3. 编辑1:删除了对ptr&的引用ptr2Array因为人们误解了这个问题。

4 个答案:

答案 0 :(得分:1)

ptr&arr之间的主要区别在于它们是两种不同的指针类型。

考虑一下:

*ptr = 10; // Valid
*ptr2Array = 10; // Not valid.

您需要使用:

(*ptr2Array)[0] = 10; 

ptr + 1 = (void*)ptr + sizeof(int)
ptr2Array + 1 = (void*)ptr2Array + sizeof(arr)

ptrptr+1之间的数字偏移为sizeof(int) ptr2Arrayptr2Array+1之间的数字偏移量为sizeof(int)*10

答案 1 :(得分:0)

  

考虑到arr [0]是否有任意位置0x100,那么为什么arr   和& arr有相同的价值?编译器究竟如何处理这两个问题   表达式以及它们如何在内存中真正实现?

因为数组是内存地址。指针是存储另一个对象的地址的对象。数组一个内存地址,在大多数情况下它会衰减为指向第一个元素的指针。使用% Translation and anti-translation matrix translate = [1 0 0 -centroide(1); 0 1 0 -centroide(2); 0 0 1 0; 0 0 0 1]; anti_translate = [1 0 0 centroide(1); 0 1 0 centroide(2); 0 0 1 0; 0 0 0 1]; % Rotation matrix rotate = [cosd(-orientation) -sind(-orientation) 0 0; sind(-orientation) cosd(-orientation) 0 0; 0 0 1 0; 0 0 0 1]; % Temporary cell array for data transformation data_vector = cell(size(RCb,1),size(RCb,2),size(RCb,3)); % Cell array for transformed data storage transformed_data = cell(size(RCb,3),1); for i = 1:(size(RCb,3)) transformed_data{i} = zeros(3, size(RCb,1)*size(RCb,2)); end for i = 1:size(RCb,3) % temporal dimension for j = 1:size(RCb,2) % x dimension for k = 1:size(RCb,1) % y dimension % [x y z] vector data_vector{k,j,i} = [j,k,RCb(k,j,i),1]'; % translation data_vector{k,j,i} = translate*data_vector{k,j,i}; % rotation data_vector{k,j,i} = rotate*data_vector{k,j,i}; % anti-translation data_vector{k,j,i} = anti_translate*data_vector{k,j,i}; data_vector{k,j,i} = data_vector{k,j,i}(1:3); transformed_data{i}(:,((j-1)*size(RCb,1)+k)) = data_vector{k,j,i}; end end end %%%% Test %%%% : image at 100 ms figure, imagesc(transformed_data{100}(2,:),transformed_data{100}(1,:),transformed_data{100}(3,:)); 运算符的地址恰好超出了这些常见情况。

有三个条件,数组名称​​不会衰减成指向其第一个元素的指针:

  1. 这是&
  2. 的操作数
  3. 其地址是与sizeof运算符
  4. 一起使用的
  5. 这是一个字符串文字
  6. 是的,&array具有相同的地址,但正如您所说,它们的类型不同。

      

    在C中使用& arr到底有什么用?既然,arr已经是了   地址,为什么'&'操作员甚至允许它?

    它是一种类似于任何其他类型的指针类型。如果你想构建一个指向数组的指针数组怎么办?它的用法几乎与任何其他指针类型相同。

答案 2 :(得分:0)

1:

看看排队等候的人 注意第一个排队的人如何准确地站在线的起始位置 同样的事情适用于数组的起始位置和第一个元素所在的位置。

作为一个例子,这里是一个由内存中列出的四个零char数组的草图:

Address:   0x10 0x11 0x12 0x13
Elements: | 0  | 0  | 0  | 0  |

数组的地址0x10与第一个元素的地址相同。

2:

arr不是地址,而是一个值为地址的变量 &arr是变量的地址,而不是其值 这与int x = 23;完全相同,&x不是数字23的地址,而是变量x的地址。
&&x是非法的,因为您无法获取值的地址(例如&(1 + 1)同样非法)。

可以使用例如阵列的地址。对于bounds-safe参数传递:

/* This function only takes pointers to 10-element arrays. */ 
void foo(int (*x)[10]);

int a[10];
foo(&a); /* OK */
int c[3][10];
foo(&c[1]); /* OK */
int b[11];
foo(&b); /* Doesn't compile */
foo(a); /* Also doesn't compile */

(更正式地说,这个讨论会引用“rvalue”和“lvalue”而不是“value”和“variable”,但我认为这并不能澄清语言律师之外的任何事情。)

答案 3 :(得分:-1)

  

我很难理解为什么这两者具有相同的价值?

让我们降低抽象级别。什么& arr真正意味着什么?当编译成汇编时, arr 只是一个符号,即标记的内存地址,所以你要求的符号的内存地址本身就是好的。

(gdb) x arr
0x7fffffffe970: 0x00400410
(gdb) x &arr
0x7fffffffe970: 0x00400410