C ++中的数组和指针 [英] Array and pointers in c++

查看:105
本文介绍了C ++中的数组和指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常听到数组的名称是指向内存块的常量指针,因此像这样的语句

  int a [ 10]; 

  int * const p = a; 

在某种意义上必须相等,因为p是指向与数组a相同的内存块的指针[]并且也可能不会更改为指向内存中的另一个位置。



但是,如果您尝试打印这两个指针的大小,则会得到不同的结果:

  cout<< sizeof(a); //输出10个整数元素的大小

  cout<< sizeof(p); //输出指向int 

的sizeof指针为什么编译器将这两个区别对待?从编译器的角度来看,数组和指针之间的真正关系是什么?

解决方案


我经常听到数组的名称是指向内存块的常量指针


您经常被误导-或您只是被误解了。数组不是指向内存块的常量指针。数组是一个包含一系列子对象的对象。所有对象都是一块内存。指针是一个包含对象地址的对象,即它指向该对象。


因此在下面的引用中, a 是一个数组, p 指向 a 中的第一个子对象。


< blockquote>

  int a [10]; 

  int * const p = a; 

必须相等,因为p是指向与数组a []相同的内存块的指针,并且可能不会更改为指向内存中的另一个位置。


如果这是您对equal的定义,那么它也适用于非数组对象:

  char c; 
int * const p =& c;

此处 p 指向与<$相同的内存c $ c> c 并且可能不会更改为指向内存中的另一个位置。这是否意味着 char 对象是等于对象?指针?否。数组也不是。


但是不是a(数组的名称),它是指向s相同元素的常量指针。数组?


否,数组名称不是常量指针。就像 char 的名称不是常量指针一样。


数组的名称成立是数组中第一个元素的地址,对吧?


让我们更笼统一点,这不特定于数组。变量的名称持有地址。变量命名的对象的名称。该地址不是持有的。在运行时在内存中。它是持有的由编译器在编译时进行。当您对变量进行运算时,编译器确保对对象的正确地址执行了操作。


数组的地址始终与第一个元素的地址相同(子对象)。因此,该名称确实确实-至少在概念上确实-保留了相同的地址。


如果我使用的是 *(a + 1),与 a [1] 相同,对吧? [typo fixed]


对。我将详细说明:在指针的情况下,一种只是编写另一种的另一种方法。哦,但是 a 不是指针!这里是要注意的地方:数组操作数被隐式转换为指向第一个元素的指针。这种隐式转换称为衰减。这是数组类型的特殊功能-它的特殊功能可能使理解指针和数组之间的差异最困难。


因此,即使数组名称不是t一个指针,它可以衰减为一个指针。在某些情况下,名称并不总是会变成指针。当您使用 operator [] 时,它会衰减,而当您使用 operator + 时,它会衰减。当您将数组传递给接受指向子对象类型的指针的函数时,它会衰减。当您使用 sizeof 时,它不会衰减;当您将其传递给通过引用接受数组的函数时,它不会衰减。


I often hear that the name of an array is constant pointer to a block of memory therefore statement like

int a[10];

and

int * const p= a;

must be equal in a sense that p is pointer that points to the same block of memory as array a[] and also it may not be changed to point to another location in memory.

However if you try to print sizeof these two pointers you get different results:

cout<< sizeof(a); // outputs size of 10 integer elements

While

cout<< sizeof(p); // outputs sizeof pointer to int

So, why do compilers treat these two differently? What's the true relation between arrays and pointers from compiler point of view?

解决方案

I often hear that the name of an array is constant pointer to a block of memory

You've often been mislead - or you've simply misunderstood. An array is not a constant pointer to a block of memory. Array is an object that contains a sequence of sub-objects. All objects are a block of memory. A pointer is an object that contains an address of an object i.e. it points to the object.

So in the following quote, a is an array, p points to the first sub-object within a.

int a[10];

and

int * const p= a;

must be equal in a sense that p is pointer that points to the same block of memory as array a[] and also it may not be changed to point to another location in memory.

If that is your definition of equal, then that holds for non-array objects as well:

char c;
int * const p = &c;

Here p "points to the same memory as c" and may not be changed to point to another location in memory. Does that mean that char objects are "equal" to pointers? No. And arrays aren't either.

But isn't a (the name of the array), a constant pointer that points to the same element of the array?

No, the name of the array isn't a constant pointer. Just like name of the char isn't a constant pointer.

the name of an array holds the address of the first element in the array, right?

Let's be more general, this is not specific to arrays. The name of a variable "holds the address" of the object that the variable names. The address is not "held" in the memory at run time. It's "held" by the compiler at compile time. When you operate on a variable, the compiler makes sure that operations are done to the object at the correct address.

The address of the array is always the same address as where the first element (sub-object) of the array is. Therefore, the name indeed does - at least conceptually - hold the same address.

And if i use *(a+1), this is the same as a[1], right? [typo fixed]

Right. I'll elaborate: One is just another way of writing another in the case of pointers. Oh, but a isn't a pointer! Here is the catch: The array operand is implicitly converted to a pointer to first element. This implicit conversion is called decaying. This is special feature of array types - and it is the special feature which probably makes understanding the difference between pointers and arrays difficult the most.

So, even though the name of the array isn't a pointer, it can decay into a pointer. The name doesn't always decay into a pointer, just in certain contexts. It decays when you use operator[], and it decays when you use operator+. It decays when you pass the array to a function that accepts a pointer to the type of the sub-object. It doesn't decay when you use sizeof and it doesn't decay when you pass it to a function that accepts an array by reference.

这篇关于C ++中的数组和指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆