简体   繁体   English

为什么地址运算符(&)对于通过函数传递的数组很重要?

[英]Why is the address operator (&) important for an array being passed through a function?

I am having trouble understanding how the & operator works and its importance. 我无法理解&运算符的工作方式及其重要性。

I found this example online: 我在网上找到了这个例子:

 #include <stdio.h>

void main()
{
  int a = 10;
  printf("\nValue of n is : %d" ,n);
  printf("\nValue of &n is : %u", &n);
}

Output : 输出:

Value of  n is : 10
Value of &n is : 1002

Firstly, why does the &n print out those two extra numbers? 首先,为什么&n打印出这两个额外的数字?

Secondly, why is this important? 其次,为什么这很重要?

The & operator is the "address of" operator. &运算符是运算符的“地址”。 so &a means the address of a , not just the value of a. 因此&a表示&aaddress of a ,而不仅仅是a的值。

What this is telling you is that the address of a is 1002 (or as dreamlax pointed out, quite possibly not the real address due to oddities with how printf is being used), even though the value is 10 . 这告诉您的是,即使该值为10 ,a的地址也为1002 (或如dreamlax所指出的,由于使用printf的方式存在奇数,因此很有可能不是真实地址)。 Note that there is no strict correlation between the two values, you could just as easily have a=121765 and &a=494260 . 请注意,两个值之间没有严格的相关性,您可以轻松地获得a=121765&a=494260

Knowing the address of a variable allows you to manipulate that specific value/object the variable is "referring" or "pointing" to. 知道变量的地址后,您就可以操纵该变量“引用”或“指向”的特定值/对象。 If you wish for a function to manipulate that specific value/object rather than manipulate a copy, you should pass the variable's address. 如果希望函数操作该特定值/对象而不是操作副本,则应传递变量的地址。

Take the following code (not necessarily complete code): 使用以下代码(不一定是完整的代码):

int main(void)
{
    int a = 10;
    doIt(a);
    printf("after doIt: %d", a);
    doItByReference(&a);
    printf("after doItByReference: %d", a);
}

void doIt(int val)
{
    val = 13;
}

void doItByReference(int *val)
{
    *val = 15;
}

Calling doIt passes the value held by a , and a new integer variable at a different address gets that value copied into it. 调用doIt会传递a持有的值,而位于不同地址的新整数变量会将该值复制到其中。 The function is free to make any changes to this duplicate copy and no modifications will be seen in the original a variable. 该功能是免费的,使这个副本的任何改变,没有修改将在原可以看出a变量。

However, calling doItByReference passes the address of a . 但是,调用doItByReference传递的地址a Any changes made to the value at the given address will reflect as changes made to a . 在给定地址的值所做的任何更改将反映为所做的更改a

This by itself is useful if you want to make changes to a given object and have those changes be reflected in the original copy. 如果您想对给定的对象进行更改并使这些更改反映在原始副本中,那么这本身就很有用。 However, even if you don't want to modify a value in the original copy this is useful performance wise because you avoid having to copy any values. 但是,即使您不想修改原始副本中的值,这也是有用的性能选择,因为您不必复制任何值。 For a simple int which may be say 4 bytes (exact value isn't important), this is insignificant. 对于一个简单的int,可以说是4个字节(确切的值并不重要),这无关紧要。

However, say you had a struct which was thousands or millions of bytes: 但是,假设您有一个成千上万个字节的结构:

struct LargeStruct
{
    int buffer[134217728];
};

void doIt(LargeStruct buffer)
{
    // ... do something
}

void doItByReference(LargeStruct *buffer)
{
    // ... do something
}

This time, every call to doIt will have to copy the entire LargeStruct object which is millions of bytes, where-as a call to doItByReference simply uses the existing object and no copy is required. 这一次,每次对doIt调用都必须复制整个LargeStruct对象,该对象为数百万个字节,而对doItByReference的调用仅使用现有对象,而无需复制。

n is a variable. n是一个变量。 It represents a value. 它代表一个值。
&n is a reference to n. &n是对n的引用。 It represents the address in memory where n is store. 它表示存储n的内存中的地址。

As to why it is important: 关于它为什么重要的原因:

When you pass an array in C, the function is usually expecting a pointer. 当您使用C传递数组时,该函数通常需要一个指针。 (ie: int* as opposed to just int). (即:int *,而不是int)。
If you were to pass 'n' to the function, it would complain when compiling because the types don't match up (n=int, function expects int*). 如果将“ n”传递给函数,则在编译时会抱怨,因为类型不匹配(n = int,函数期望int *)。
If you pass in &n, however you are passing in an address to 'n' which is what the function expects. 如果您传入&n,那么您会将一个地址传递给'n',这正是函数所期望的。

To print out an address in C, you normally should use %p in stead of %u . 要在C中打印地址,通常应使用%p代替%u

Note %p prints out address in hexadecimal number. 注意%p以十六进制数输出地址。

The address of operator, & , returns the memory address of the following variable. 运算符&的地址返回以下变量的内存地址。 This is important because: 这很重要,因为:

  1. it allows referring to large memory chunks (structures, arrays, dynamically allocated unstructured memory regions) with a light weight handle 它允许使用轻量级句柄引用大型内存块(结构,数组,动态分配的非结构化内存区域)

  2. it provides means to access internal representations of data structures 它提供了访问数据结构内部表示的方法

  3. it allows us to process different types of data through the same interface 它允许我们通过同一接口处理不同类型的数据

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM