【问题标题】:C array pointer arithmeticC数组指针算法
【发布时间】:2016-06-25 17:07:07
【问题描述】:

我正在尝试重写我的代码,该代码采用用户输入数组,转到函数并在每个数字之间添加零并将其保存到数组 2。我的源代码工作得很好,但我在尝试这样做时遇到了麻烦它使用指针算法仅用于函数访问每个数组元素,它不能是子脚本。 你能告诉我关于我的代码或如何做到这一点的建议吗?

源代码:

#include <stdio.h>

void insert0(int n, int a1[], int a2[]);

int main(void) {

  int i;     
  int n;

  printf("Please enter the length of the input array: ");   
    scanf("%d", &n);

  int a[n];   
  int b[2*n];  

  printf("Enter %d numbers for the array: ", n);   
    for (i = 0; i < n; i++){     
      scanf("%d", &a[i]);
    }

  insert0(n, a,  b);

  printf("Output array:");   
    for (i = 0; i < 2*n; i++){
      printf(" %d", b[i]);   
        printf("\n");
    }
    return 0; 
}

void insert0(int n, int a[], int b[]) {

  int i, j = 0; 

  for(i = 0; i < n; i++, j+=2){    
    b[j]= a[i];    
      b[j+1] = 0; 
  }
}

我的算术:

   #include <stdio.h>

    void insert0(int n, int *a1, int *a2);

    int main(void) {

      int i;     
      int n;

      printf("Please enter the length of the input array: ");   
        scanf("%d", &n);

      int a1[n];   
      int a2[2*n];  

      printf("Enter %d numbers for the array: ", n);   
        for (i = 0; i < n; i++){     
          scanf("%d", &a2[i]);
        }

//not sure if this is how you call it, I've seen it called with arr
      insert0(n, a1, a2); 

      printf("Output array:");   
        for (i = 0; i < 2*n; i++){
          printf(" %d", a2[i]);   
            printf("\n");
        }
        return 0; 
    }

    void insert0(int n, int *a1, int *a2) {

      int *p;
      int j = 0;

        // I think I translated this properly     
        for(p = a1; p < a1+n; p++, j+=2){
          a2+j = a1+p;  
          //unsure how to get a2[j+1] to still work here with pointer  
            a2(j+1) = 0; 
      }
    }

【问题讨论】:

    标签: c arrays pointers pointer-arithmetic


    【解决方案1】:

    您需要取消引用您的指针。

    a2+j = a1+p;
    

    没有任何作用。这就是说“将地址 a2 + j 设置为地址 a1 + p”,这是您无法做到的。要将存储在 a2+j 的值设置为存储在 a1+p 的值,您需要这样做:

    *(a2+j) = *(a1+p)
    

    您需要将指针算术括在括号内,并在其上使用解引用运算符。

    a1 + p 不是您想要的地址。 p 存储的是实际地址,而不仅仅是偏移量,所以您可能只需要 p

    【讨论】:

      【解决方案2】:

      问题一:

      在您的代码中:

      int a1[n];   
      int a2[2*n];  
      
      printf("Enter %d numbers for the array: ", n);   
      
      for (i = 0; i < n; i++)
      {     
          scanf("%d", &a2[i]); //maybe you are using wrong array to input elements 
      }
      
      • 我认为在这里您需要将元素扫描到 a1 数组中,因为它的大小是 n 并且您正在扫描 n 元素...
      • 但是您正在将元素扫描到 a2 中,并且在 insert0() 函数中,您正在借助未初始化的 a1 重写 a2 的元素...

      解决方案:

      扫描元素到a1

      for (i = 0; i < n; i++)
      {     
          scanf("%d", &a1[i]); //scanning into `a1`
      }
      

      问题 2:

      • 注意:另一点需要注意的是,对于a2[](2*n)-1 元素就足够了,因为您只在数字之间分配零,即,

      示例:

      1,1,1 // 3 elements
      
      1,0,1,0,1 // (2*3)-1=5 elements after inserting
      

      解决方案:

          printf("Please enter the length of the input array: ");
          scanf("%d", &n);
      
          int a1[n];
          int a2[(2*n)-1];  
      

      最后……

      但我在尝试让它使用指针算法来访问每个数组元素时遇到了麻烦,它不能是子脚本。

      是的,可以使用下标!

      这样:

      void insert0(int n, int *a1, int *a2)
      {
      
          int j = 0;
      
          for(j=0;j<(2*n)-1; j++)
          {
              if(j%2!=0)
                  a2[j]=0;
              else
                  a2[j]=a1[j/2];
          }
      }
      

      所以您的 代码 将是:

        #include <stdio.h>
      
        void insert0(int n, int *a1, int *a2);
      
        int main(void) 
        {
      
          int i;
          int n;
      
          printf("Please enter the length of the input array: ");
          scanf("%d", &n);
      
          int a1[n];
          int a2[(2*n)-1];
      
          printf("Enter %d numbers for the array: ", n);
          for (i = 0; i < n; i++)
          {
            scanf("%d", &a1[i]);
          }
      
          insert0(n, a1, a2);
      
          printf("Output array:");
          for (i = 0; i < 2*n-1; i++)
          {
              printf(" %d", a2[i]);
              printf("\n");
          }
          return 0;
      }
      
      void insert0(int n, int *a1, int *a2)
      {
      
          int j = 0;
      
          for(j=0;j<(2*n)-1; j++)
          {
              if(j%2!=0)
                  a2[j]=0;
              else
                  a2[j]=a1[j/2];
          }
      }
      

      输入:

      3
      1 2 3
      

      输出:

      1
      0
      2
      0
      3
      

      【讨论】:

      • 你在这里使用 if else 语句的方式非常有趣。我从来没有想到这一点。尽管如此,还是很好且很有帮助的回复。
      【解决方案3】:

      此回复并非旨在演示使用指针运算的效率,而是展示数组索引(下标)如何转换为指针运算,应用于您的代码。请查看包含来自 C 标准的有价值信息的 this SO post

      您的代码也很少有逻辑错误,读取和写入错误的数组等……您可以自己轻松找到它们。这是一个有效的修复:

      #include <stdio.h>
      
      void insert0(int n, int *a1, int *a2) {
        int p;    //just a normal int for counter
        int j = 0;
      
          for(p = 0; p < n; p++, j+=2){
            *(a2+j) = *(a1+p);   //values pointed at are getting assigned
                                 //equivalent to a2[j] = a1[p]
            if(p < n - 1 )       //we insert only between numbers
              *(a2 + j + 1) = 0; //pointer pointing at memory into which 0 is copied incremented by 1
          }
       }
      
      
      int main(void) {
        int i;     
        int n;
      
        printf("Please enter the length of the input array: ");   
          scanf("%d", &n);
      
        int a1[n];   
        int a2[2*n];  //one element too long, should be a2[n+n-1];
      
        printf("Enter %d numbers for the array: ", n);   //reading into smaller array
          for (i = 0; i < n; i++){     
            scanf("%d", &a1[i]);
          }
      
        insert0 (n, a1, a2); //this is OK
      
        printf("Output array: ");   
        for (i = 0; i < 2*n - 1; i++){
           printf(" %d", a2[i]);              //printing from the bigger, zero-padded array
        }
        printf("\n");
        return 0; 
      }
      

      【讨论】:

      • 请 DVer 发表评论以帮助改进回复?谢谢
      • 您的回复很扎实,很容易演示如何使用指针算术,在我看来(指针算术的新手)它是直截了当的,不需要改进。我会使用它,并且将来我必须使用指针算法时可能会再次回顾它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多