更改为指针算术

时间:2016-02-21 03:40:01

标签: c pointers pointer-arithmetic

我是C的新手,我在弄清楚如何使用它们时遇到了很多麻烦。

我有一段代码,在void函数中有一些指针算法:

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;
}

我正在尝试将其完全更改为仅使用指针算法而没有循环索引变量。到目前为止,我已经得到了这个:

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;
}

但是我的理解是不是和上面的第一段代码完全相同?我错过了什么吗?谢谢你的帮助

3 个答案:

答案 0 :(得分:3)

如果您正在努力解决指针,那么如何理解指针的简短版本就是理解它只是一个包含地址的变量以其他方式作为。采用正常变量int x = 5;,其中x包含立即值 5

另一方面,指针不包含立即值,但包含可以找到立即值(或其他指针)的地址在记忆中。这为您使用指针提供了相当多的灵活性。正如您可以在x上使用算术(例如x++;)来增加5 - &gt; 6,当您将指针递增到数组时,指针现在指向数组中的下一个地址。

因此,如果您已声明int a[] = {3, 5, 7, 9};,那么在为a分配为存储的连续内​​存块中,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,并仅使用内存地址位置信息及其值在function中执行相同的操作。这就是 pointer-arithmetic 可以像数组索引一样用来设置,比较,删除数组中的值的地方。使用指针迭代数组时,通常会声明一个指针,用于迭代目的,这样就不会丢失内存块的起始地址

值得庆幸的是,当指针(或由于转换引起的数组)作为参数传递给函数时,该函数会接收指针副本而不是原始地址。调用函数中的指针。您仍然可能需要保存一个包含副本原始地址的指针,但这只取决于您需要在功能中执行的操作。

如果要在function递增指针中重新实现相同的逻辑而不是递增索引'i',那么您将需要处理{{1}中第一个指针位置的增量设置默认a时设置{}}和b。虽然您可以通过迭代*b=0;简单地跳过每个使用索引的第一个字符,但是如果采用该方法,则必须自己增加指针。您可以通过简单地跳过for (i = 1;...保存其原始地址的迭代来处理循环:

a

或者,您可以在开始循环之前预先增加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' */ } a(例如b)以确保您正在处理a++, b++;中的第二个和第一个字符a声明。一个例子是:

if

由于您似乎对指针的解除引用方面有一个公平的处理来操作内存中指向的值,我会留给您。一个简短的比较示例允许您运行不带参数的代码(或使用不以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; } 开头的参数)来查看数组上原始函数的结果,或者提供以'f'开头的参数调用指针使用函数:

'f'

示例使用/输出

#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;
}

查看功能和示例,如果您有任何疑问,请告诉我。我希望这会有所帮助。

答案 1 :(得分:0)

它们不一样,您必须在a正文中用p替换for,并使用q指针修改b。< / p>

void function(int n, int *a, int *b)
{
   *b = 0;
    for (int *p = a + 1, *q = b ; p < a + n ; ++p, ++q)
    {
       if (*p == *(p - 1))
          *q = 0;
       else
          *q = 1;
    }
}

答案 2 :(得分:0)

您的程序有一些未使用的变量。不要忽视编译器的警告。

这就是我猜你的意思:

void function0(int n, int *a, int *b)
{
    b[0] = 0;
    int i;
    for (i = 1; i < n; i++)
        if(a[i] == a[i-1])
            b[i] = 0;
        else
            b[i] = 1;
}

function0() 语法

相同
void function1(int n, int *a, int *b)
{
    *b = 0;
    int i;
    for (i = 1; i < n; i++)
        if(*(a + i) == *(a + i - 1))
            *(b + i) = 0;
        else
            *(b + i) = 1;
}

功能与:

相同
void function2(int n, int *a, int *b)
{
    *b = 0;
    int *p, *q;
    for (p = a + 1, q = b; p < a + n; p++, q++)
        if(*p == *(p - 1))
            *q = 0;
        else
            *q = 1;
}