我如何使用指针?在C.

时间:2016-03-25 01:34:49

标签: c pointers

我对C编程很新,我对指针如何工作感到困惑。如何使用ONLY指针复制值,例如...仅使用指针将x中的值复制到y中。

library(dplyr)
df %>%
  group_by(site) %>% 
  mutate(avg.1 = mean(rf, na.rm=TRUE)) %>% 
  group_by(mon) %>% 
  mutate(avg.2 = mean(rf, na.rm=TRUE)) %>% 
  group_by(region, year) %>%
  mutate(avg.3= mean(rf, na.rm=TRUE))

4 个答案:

答案 0 :(得分:2)

这很简单。 &返回变量的地址。所以当你这样做时:

ptr1 = &x;

ptr1指向x,或保留变量x的地址。

现在假设您要复制ptr1指向的变量中的值。您需要使用*。当你写

y = ptr1;

ptr1的值在y中,而不是ptr1指向的值。要设置ptr1所指向的变量的值,请使用*

y = *ptr1;

这会将变量ptr1的值指向y,或者简单地说,将x的值放在y中。这是因为ptr1指向x

要在下次解决此类简单问题时,请在编译期间启用编译器的所有警告和错误。

如果您使用的是gcc,请使用-Wall-Wextra-Wall将启用所有警告,-Wextra会将所有警告变为错误,并确认您不会忽略警告。

答案 1 :(得分:1)

什么是指针?

指针是C中的特殊基本类型。除了int类型存储的小数,指针存储了内存地址。

如何创建指针

对于所有类型和用户类型(即结构,联合),您必须执行以下操作:

Type * pointer_name;
int * pointer_to_int;
MyStruct * pointer_to_myStruct;

如何指定指针

正如我所说,我指针存储了内存地址,因此&运算符返回变量的内存地址。

int a = 26;
int *pointer1 = &a, *pointer2, *pointer3; // pointer1 points to a
pointer2 = &a; // pointer2 points to a
pointer3 = pointer2; // pointer3 points to the memory address that pointer2 too points, so pointer3 points to a :)

如何使用指针值

如果要访问指针的值,必须使用*运算符:

int y = *pointer1; // Ok, y = a. So y = 25 ;)
int y = pointer1; // Error, y can't store memory address.

通过指针编辑变量的值

要通过指针更改变量的值,首先,您必须访问该值然后更改它。

*pointer1++; // Ok, a = 27;
*pointer1 = 12; // Ok, a = 12;
pointer1 = 12; // Noo, pointer1 points to the memory address 12. It's a problem and maybe it does crush your program.
pointer1++; // Only when you use pointer and arrays ;).

答案 2 :(得分:1)

长指针说明

在向已经知道如何编程的人解释什么指针时,我发现使用数组术语引入它们非常容易。

在所有抽象之下,你的计算机内存实际上只是一个大数组,我们称之为memmem[0]是内存中的第一个字节,mem[1]是第二个字节,依此类推。

程序运行时,几乎所有变量都存储在内存中。在代码中看到变量的方式非常简单。您的CPU知道一个数字,该数字是mem(我称之为base)中您的程序数据所在的索引,实际代码只是使用{{base来引用变量1}}和偏移。

对于一段假设的代码,让我们看一下:

byte foo(byte a, byte b){
    byte c = a + b;
    return c;
}

一个天真但很好的例子,它实际上看起来像编译之后看起来像是:

  • 移动base为三个新字节腾出空间
  • mem[base+0](变量a)设置为a
  • 的值
  • mem[base+1](变量b)设置为b
  • 的值
  • mem[base+2](变量c)设为总和mem[base+0] + mem[base+1]
  • 将返回值设置为mem[base+2]
  • 在调用函数
  • 之前将base移回原位

具体发生的具体细节是平台和约定,但通常看起来没有任何优化。

正如示例所示,a bc作为特殊实体的概念出现了。编译器在生成相关代码时计算为变量提供的偏移量,但最终结果仅处理base和硬编码偏移量。

什么是指针?

指针只是引用mem数组中索引的一种奇特方式。实际上,指针实际上只是一个数字。这就是全部; C只是给你一些语法,使它更加明显,它应该是mem数组中的索引而不是某个任意数字。

引用和解除引用意味着什么?

当你引用一个变量(比如&var)时,编译器会检索它为变量计算的偏移量,然后发出一些大致意味着"返回base之和的代码。变量的偏移"

这是另一段代码:

void foo(byte a){
    byte bar = a;
    byte *ptr = &bar;
}

(是的,它没有做任何事情,但它是为了说明基本概念)

这大致转换为:

  • 移动base为两个字节和一个指针
  • 腾出空间
  • mem[base+0](变量a)设置为a
  • 的值
  • mem[base+1](变量条)设置为mem[base+0]
  • 的值
  • mem[base+2](变量ptr)设置为base+1的值(因为1是用于条形的偏移量)
  • base移回原先的位置

在这个例子中,您可以看到,当您引用变量时,编译器只使用内存索引作为值,而不是在该索引的mem中找到的值。

现在,当您取消引用指针(如*ptr)时,编译器会将指针中存储的值用作mem中的索引。例如:

void foo(byte* a){
    byte value = *a;
}

说明:

  • 移动base为指针和字节腾出空间
  • mem[base+0](变量a)设置为a
  • 的值
  • mem[base+1](变量值)设为mem[mem[base+0]]
  • base移回原来的位置

在此示例中,编译器使用内存中的值,其中该值的索引由内存中的另一个值指定。这可以达到你想要的深度,但通常只有一到两个深度。

一些注释

由于引用的变量实际上只是数字,因此您无法引用引用或为引用赋值,因为base+offset是我们从第一个引用获得的值,它不存储在内存中,因此我们无法获得存储在内存中的位置。 (&var = value;&&var是非法声明)。但是,您可以取消引用引用,但这只会让您回到起始位置(*&var是合法的)。

另一方面,由于解除引用的变量 是内存中的值,因此您可以引用解除引用的值,取消引用解除引用的值,并将数据分配给解除引用的变量。 (*var = value;&*var**var都是合法陈述。)

此外,并非所有类型都是一个字节大,但我简化了示例,使其更容易掌握。实际上,在大多数机器上,指针会占用内存中的几个字节,但我将其保留在一个字节以避免混淆问题。一般原则是一样的。

总结

  • 记忆只是一个很大的阵列,我打电话给mem
  • 每个变量都存储在内存中我调用varlocation的位置,该位置由编译器为每个变量指定。
  • 当计算机正常引用变量时,它最终在最终代码中看起来像mem[varlocation]
  • 当您引用变量时,您只需在结束代码中获得varlocation的数值。
  • 当您取消引用该变量时,您会在代码中获得mem[mem[varlocation]]的值。

tl; dr - 实际回答问题......

//Your variables x and y and ptr
int x, y;
int *ptr;
//Store the location of x (x_location) in the ptr variable
ptr = &x; //Roughly: mem[ptr_location] = x_location;
//Initialize your x value with scanf
//Notice scanf takes the location of (a.k.a. pointer to) x to know where 
//to put the value in memory
scanf("%d", &x); 
y = *ptr; //Roughly: mem[y_location] = mem[mem[ptr_location]]
//Since 'mem[ptr_location]' was set to the value 'x_location',
//then that line turns into 'mem[y_location] = mem[x_location]'
//which is the same thing as 'y = x;'

总的来说,正如其他人已经指出的那样,你只是错过了取消引用该变量的明星。

答案 3 :(得分:0)

只需将y = ptr1;更改为y = *ptr1;

这是因为ptr1是指向x的指针,要获得x的值,您必须取消引用 ptr1添加前导*