指针到底存储什么? (C++)

发布于 2024-07-23 23:08:45 字数 194 浏览 2 评论 0原文

我知道指针存储它们指向的值的地址,但是如果将指针的值直接显示到屏幕上,您会得到一个十六进制数。 如果该数字正是指针存储的数字,则表示

pA = pB; //both are pointers

您正在复制地址。 那么,在处理像 int 和 bool 这样非常小的项目时,使用指针会不会产生更大的开销?

I know that pointers store the address of the value that they point to, but if you display the value of a pointer directly to the screen, you get a hexadecimal number. If the number is exactly what the pointer stores, then when saying

pA = pB; //both are pointers

you're copying the address. Then wouldn't there be a bigger overhead to using pointers when working with very small items like ints and bools?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

抽个烟儿 2024-07-30 23:08:47

内存中的地址。 指向某个地方! :-)

An address in memory. Points to somewhere! :-)

丿*梦醉红颜 2024-07-30 23:08:47

是的,你是对的,无论是在速度还是内存方面。

指针几乎总是比标准int占用更多的字节,尤其是boolchar数据类型。 在现代机器上,指针通常为 8 个字节,而 char几乎 始终只有 1 个字节。

在此示例中,从 Foo 访问 charbool 比从 Bar 访问需要更多的机器指令:

struct Foo
{
    char * c; // single character
    bool * b; // single bool
};

struct Bar
{
    char c;
    bool b;
};

。 .. 如果我们决定创建一些数组,那么 Foo 数组的大小将增大 8 倍 - 并且代码更加分散,因此这意味着您最终将得到一个更多缓存未命中。

#include <vector>

int main()
{
    int size = 1000000;
    std::vector<Foo> foo(size);
    std::vector<Bar> bar(size);

    return 0;
}

正如 dmckee 指出的,单字节 bool 的单个副本和指针的单个副本一样快:

bool num1, num2,* p1, * p2;
num1 = num2; // this takes one clock cycle
p1 = p2; // this takes another

正如 dmckee 所说,当您使用 64 位体系结构时确实如此。

但是,复制 int、bool 和 char 数组可能会快得多,因为我们可以将它们的多个压缩到每个寄存器上:

#include <iostream>

int main ()
{
    const int n_elements = 100000 * sizeof(int64_t);

    bool A[n_elements];
    bool B[n_elements];

    int64_t * A_fast = (int64_t *) A;
    int64_t * B_fast = (int64_t *) B;

    const int n_quick_elements = n_elements / sizeof(int64_t);

    for (int i = 0; i < 10000; ++i)
        for (int j = 0; j < n_quick_elements; ++j)
            A_fast[j] = B_fast[j];

    return 0;
}

STL 容器和其他优秀的库使用 type_traits (is_trivially_copyable) 和 std::memcopy 为我们做这类事情。 假装指针总是一样快而使用指针会阻止这些库的优化。

结论:这些示例似乎很明显,但是当您需要获取/授予对原始对象的访问权限时,仅在基本数据类型上使用指针/引用。

Yes, you're right, both in terms of speed and memory.

Pointers almost always take up more bytes than your standard int and, especially, bool and char data types. On modern machines pointers typically are 8 bytes while char is almost always just 1 byte.

In this example, accessing the the char and bool from Foo requires more machine instructions than accessing from Bar:

struct Foo
{
    char * c; // single character
    bool * b; // single bool
};

struct Bar
{
    char c;
    bool b;
};

... And if we decide to make some arrays, then the size of the arrays of Foo would be 8 times larger - and the code is more spread-apart so this means you'll end up having a lot more cache misses.

#include <vector>

int main()
{
    int size = 1000000;
    std::vector<Foo> foo(size);
    std::vector<Bar> bar(size);

    return 0;
}

As dmckee pointed out, a single copy of a one-byte bool and a single copy of a pointer are just as fast:

bool num1, num2,* p1, * p2;
num1 = num2; // this takes one clock cycle
p1 = p2; // this takes another

As dmckee said, this is true when you're using a 64-bit architecture.

However, copying of arrays of ints, bools and chars can be much faster, because we can squeeze multiples of them onto each register:

#include <iostream>

int main ()
{
    const int n_elements = 100000 * sizeof(int64_t);

    bool A[n_elements];
    bool B[n_elements];

    int64_t * A_fast = (int64_t *) A;
    int64_t * B_fast = (int64_t *) B;

    const int n_quick_elements = n_elements / sizeof(int64_t);

    for (int i = 0; i < 10000; ++i)
        for (int j = 0; j < n_quick_elements; ++j)
            A_fast[j] = B_fast[j];

    return 0;
}

The STL containers and other good libraries do this sort of thing for us, using type_traits (is_trivially_copyable) and std::memcopy. Using pointers under the false guise that they're always just as fast can prevent those libraries from optimising.

Conclusion: It may seem obvious with these examples, but only use pointers/references on basic data types when you need to take/give access to the original object.

胡大本事 2024-07-30 23:08:47

让我从基础开始。 首先,您必须知道什么是变量以及它们如何使用。

变量基本上是内存位置(通常包含一些值),我们使用一些标识符(即变量名称)来引用该内存位置并使用该位置存在的值。

为了更好地理解它,假设我们想要来自与当前变量相关的某个位置的内存单元的信息。 我们可以使用标识符从附近的单元格中提取信息吗?
不会。因为标识符(变量名称)只会给出该特定单元格中包含的值。

但是,如果我们能够以某种方式获得该变量所在的内存地址,那么我们可以轻松移动到附近的位置并使用它们的信息(在运行时)。

这就是指针发挥作用的地方。 它们用于存储该变量的位置,以便我们可以在需要时使用附加地址信息。

语法:要存储变量的地址,我们可以简单地使用& (address-of) 运算符。

foo = &bar 

这里 foo 存储变量 bar 的地址。

现在,如果我们想知道该地址上存在的值怎么办?

为此,我们可以简单地使用*(解除引用)运算符

value = *foo

现在我们必须存储变量的地址,我们将像变量一样需要内存。 这意味着指针也像其他变量一样存储在内存中,因此就像变量一样,我们也可以将指针的地址存储到另一个指针中。

Let me start from the basics. First of all, you will have to know what variable are and how they are used.

Variables are basically memory locations(usually containing some values) and we use some identifier(i.e., variable names) to refer to that memory location and use the value present at that location.

For understanding it better, suppose we want the information from memory cells present at some location relative to the current variable. Can we use the identifier to extract information from nearby cells?
No. Because the identifier(variable name) will only give the value contained in that particular cell.

But, If somehow we can get the memory address at which this variable is present then we can easily move to nearby locations and use their information as well(at runtime).

This is where pointers come into play. They are used to store the location of that variable so that we can use the additional address information whenever required.

Syntax: To store the address of a variable we can simply use & (address-of) operator.

foo = &bar 

Here foo stores the address of variable bar.

Now, what if we want to know the value present at that address?

For that, we can simply use the * (dereference) operator.

value = *foo

Now that we have to store the address of a variable, we'll be needing the memory the same way as we need in case of a variable. This means pointers are also stored in the memory the same way as other variables, so just like in case of variables, we can also store the address of a pointer into yet another pointer.

梦中的蝴蝶 2024-07-30 23:08:46

在某些体系结构上,由于体系结构仅支持寻址字(32 位或 64 位值),因此存在指向字符的指针的额外开销。 因此,指向字符的指针被存储为字地址和该字内字符的偏移量。 取消引用指针涉及获取单词,然后移动并屏蔽它的值以提取字符。

On some architectures there is an additional overhead of pointers to characters because the architecture only supports addressing words (32- or 64-bit values). A pointer to a character is therefore stored as a word address and an offset of the character within that word. De-referencing the pointer involves fetching the word and then shifting and masking it's value to extract the character.

只等公子 2024-07-30 23:08:46

该数字指的是它在内存中的地址。 指针的大小通常是计算机体系结构的本机大小,因此与任何其他基元类型相比,没有额外的开销。

The number refers to its address in memory. The size of a pointer is typically the native size of the computer's architecture so there is no additional overhead compared to any other primitive type.

念﹏祤嫣 2024-07-30 23:08:46

正如其他人所说,指针存储一个内存地址,“只是一个数字”,但这是一个抽象。根据处理器架构,它可能不止一个数字,例如必须添加基址和偏移量才能取消引用指针在这种情况下,开销会比地址为单个数字时稍高一些。

是的,与直接访问 int 或 bool 相比,处理器可以将变量放入寄存器中。通常在间接值超过任何开销的情况下使用,即遍历数组,

我不确定 OP 是否更关心空间或时间开销。

As others have said, a pointer stores a memory address which is "just a number' but that is an abstraction. Depending on processor architecture it may be more than one number, for instance a base and offset that must be added to dereference the pointer. In this case the overhead is slightly higher than if the address is a single number.

Yes, there is overhead in accessing an int or a bool via a pointer vs. directly, where the processor can put the variable in a register. Pointers are usually used where the value of the indirection outweighs any overhead, i.e. traversing an array.

I've been referring to time overhead. Not sure if OP was more concerned space or time overhead.

原野 2024-07-30 23:08:45

指针本质上只是一个数字。 它将地址存储在数据所在的 RAM 中。 指针本身非常小(可能与 32 位体系结构上的 int 大小相同,在 64 位体系结构上与 long 大小相同)。

尽管在使用 intint * 不会节省任何空间,但您是正确的。 但这不是重点(没有双关语)。 指针的存在是为了让您可以对事物进行引用,而不仅仅是使用事物本身。

A pointer is essentially just a number. It stores the address in RAM where the data is. The pointer itself is pretty small (probably the same size as an int on 32 bit architectures, long on 64 bit).

You are correct though that an int * would not save any space when working with ints. But that is not the point (no pun intended). Pointers are there so you can have references to things, not just use the things themselves.

你没皮卡萌 2024-07-30 23:08:45

内存地址。

这是内存中其他内容所在的位置。

指针通常是处理器的字大小,因此它们通常可以在单个指令周期内移动。 简而言之,它们速度很快。

Memory addresses.

That is the locations in memory where other stuff is.

Pointers are generally the word size of the processor, so they can generally be moved around in a single instruction cycle. In short, they are fast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文