更改为指针运算 [英] Changing to Pointer Arithmetic
问题描述
我是新来的C指针和我有很多的麻烦搞清楚如何与他们合作。
I'm new to pointers in C and I'm having a lot of trouble figuring out how to work with them.
我有这块code与一个void函数里面的一些指针运算:
I have this piece of code with some pointer arithmetic inside a void function:
void function(int n, int *a, int *b){
int *p,*q;
q = b;
int i;
*b = 0;
for (i = 1; i<n; i++)
if(*(a+i) == *(a+i-1))
*(b+i)=0;
else
*(b+i)=1;
}
我想彻底改变其只使用指针运算,没有循环索引变量。到目前为止,我已经得到了这一点:
I'm trying to change it completely to use only pointer arithmetic with no loop index variables. So far I've gotten this:
void function(int n, int *a, int *b){
int *p,*q;
q = b;
*b = 0;
for (p = a+1; p<a+n; p++)
if(*a == *a-1)
*b=0;
else
*b=1;
}
但我的理解是不是完全一样,上面的第一块code的?我缺少的东西吗?感谢您的帮助。
But to my understanding isn't it exactly the same as the first piece of code above? Am I missing something? Thanks for your help
推荐答案
如果您正在挣扎的指针的一点,如何理解短版的指针的是要了解它只是持有的地址的别的东西作为它的值的一个变量。以一个普通变量 INT X = 5;
,其中 X
包含的即时值的 5
。
If you are struggling with pointers a bit, the short version of how to understand a pointer is to understand it is simply a variable that holds an address to something else as its value. Take a normal variable int x = 5;
where x
contains the immediate-value 5
.
在另一手的指针,不包含的即时值的,但包含凡的即时值的(或其他指针),可以发现地址在记忆中。这提供了如何使用指针相当多的更大的灵活性。正如你可以使用算术X
(如 X ++;
)递增 5
- > 6
,当你增加一个的指针的一个数组,指针现在指向数组中的下一个地址。
A pointer on the other-hand, does not contain an immediate-value, but contains the address where an immediate-value (or another pointer) can be found in memory. This provides quite a bit of increased flexibility in how you use pointers. Just as you can use arithmetic on x
(e.g. x++;
) to increment 5
-> 6
, when you increment a pointer to an array, the pointer now points to the next address in the array.
所以,如果你已经声明 int类型的[] = {3,5,7,9};
,你就必须对下面的关系一个
的内存连续块分配作为存储之间的 A
:
So if you have declared int a[] = {3, 5, 7, 9};
, you would have the following relationships regarding a
among the sequential block of memory allocated as storage for a
:
a m1 m2 m3 m4 /* points to memory locations m1 -> m4 */
| 0 | 1 | 2 | 3 | /* the zero based array indexes */
| 3 | 5 | 7 | 9 | /* the values stored in m1 -> m4 */
您希望消除与数组索引工作 0-4
和函数执行相同的操作
只使用存储器地址的位置信息和它们的值。这是的指针的算术的可用于就像数组索引设置,比较,从数组中删除值。当使用指针遍历数组,你一般会声明指针使用迭代目的的这样你就不会失去的的的起始地址的为你的内存块。
You desire to eliminate working with the array indexes 0-4
and perform the same manipulations in function
using only the memory address location information and their values. This is where pointer-arithmetic can be used just like array indexing to set, compare, remove values from your array. When iterating an array using a pointer, you generally will declare a pointer to use for iteration purposes so you do not lose the start address for your block of memory.
值得庆幸的是,该函数收到的复制的指针的而不是原来的地址的为指针调用函数。你可能仍然需要保存一个指针保持原来的地址的复制的,但是这只是取决于你需要在函数做什么的
Thankfully when pointers (or arrays due to conversion) are passed as arguments to a function, the function receives a copy of the pointer and not the original address for the pointer in the calling function. You still may need to save a pointer holding the original address for the copy, but that just depends on what you need to do in the function.
如果你想重新实现相同的逻辑在函数
递增指针,而不是递增的指数我
,那么你将需要处理两个 A
和 b
当您设置的第一个指针位置的增量您默认的 * b = 0;
。虽然你可以简单地通过循环为跳过的第一个字符中的每个使用索引(i = 1; ...
,你必须增加指针本身,如果你采取这种做法。您可以处理的循环中通过简单地跳过其中 A
持有其原来的地址迭代:
If you want to re-implement the same logic in function
incrementing pointers instead of incrementing an index 'i'
, then you will need to handle the increment of the first pointer position in both a
and b
when you set your default *b=0;
. While you can simply skip over the first character in each using indexes by iterating for (i = 1;...
, you must increment the pointers themselves if you take that approach. You can handle that within the loop by simply skipping the iteration where a
holds its original address:
void functionp (int n, int *a, int *b)
{
int *p = a; /* saved the original value of the copy */
*b = 0;
for (; a < p + n; a++, b++)
if (a > p)
*b = (*a == *(a - 1)) ? 0 : 1;
else
continue; /* skip first loop where 'p == a' */
}
或者,您可以preincrement既 A
和 B
开始循环(前如 A +,b ++;
)以确保您正在解决 A
在如果
语句。一个例子将有:
Or, you can preincrement both a
and b
before starting the loop (e.g. a++, b++;
) to insure your are addressing the second and first characters in a
in your if
statement. An example there would be:
void functionp (int n, int *a, int *b)
{
int *p = a; /* saved the original value of the copy */
*b = 0;
a++, b++; /* increment both 'a' and 'b' */
for (; a < p + n; a++, b++)
*b = (*a == *(a - 1)) ? 0 : 1;
}
因为你似乎对的解引用的指针的值进行操作的方面在内存中指出,我会留给你一个公平的处理。一个简短的比较的例子让您无需参数运行code(或参数与'F'开头
)查看原有功能的阵列上的结果,或提供以开始'F'的参数
将调用指针使用功能:
Since you seem to have a fair handle on the dereferencing aspect of pointers to operate on the value pointed to in memory, I'll leave that to you. A short comparison example allows you to run the code without argument (or with argument not beginning with 'f'
) to see the results of your original function on the array, or providing an arguments that begins with 'f'
will call the pointer use function:
#include <stdio.h>
void function (int n, int *a, int *b);
void functionp (int n, int *a, int *b);
int main (int argc, char **argv) {
int a[] = {1,1,2,2,3,3,3,4};
int i, n = sizeof a/sizeof *a;
int b[n];
if (argc > 1 && *argv[1] == 'f') {
printf ("\n executing 'function'\n\n");
function (n, a, b);
}
else {
printf ("\n executing 'functionp'\n\n");
functionp (n, a, b);
}
for (i = 0; i < n; i++)
printf (" a[%d] : %d | b[%d] : %d\n",
i, a[i], i, b[i]);
return 0;
}
void function (int n, int *a, int *b) /* original function */
{
int i;
*b = 0;
for (i = 1; i < n; i++)
if(*(a+i) == *(a+i-1))
*(b+i)=0;
else
*(b+i)=1;
}
void functionp (int n, int *a, int *b) /* pointer use only function */
{
int *p = a;
*b = 0;
a++, b++; /* increment both 'a' and 'b' */
for (; a < p + n; a++, b++)
*b = (*a == *(a - 1)) ? 0 : 1;
}
示例使用/输出
$ ./bin/idx2ptr f
executing 'function'
a[0] : 1 | b[0] : 0
a[1] : 1 | b[1] : 0
a[2] : 2 | b[2] : 1
a[3] : 2 | b[3] : 0
a[4] : 3 | b[4] : 1
a[5] : 3 | b[5] : 0
a[6] : 3 | b[6] : 0
a[7] : 4 | b[7] : 1
$ ./bin/idx2ptr p
executing 'functionp'
a[0] : 1 | b[0] : 0
a[1] : 1 | b[1] : 0
a[2] : 2 | b[2] : 1
a[3] : 2 | b[3] : 0
a[4] : 3 | b[4] : 1
a[5] : 3 | b[5] : 0
a[6] : 3 | b[6] : 0
a[7] : 4 | b[7] : 1
过目功能和榜样,让我知道如果您有任何疑问。我希望这有助于。
Look over the function and the example and let me know if you have any questions. I hope this helps.
这篇关于更改为指针运算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!