更改为指针算术
我是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; }
但据我所知,它与上面的第一段代码完全不一样吗? 我错过了什么吗? 谢谢你的帮助
如果你正在努力使用指针 ,那么如何理解指针的简短版本就是理解它只是一个变量,它将地址保存为其他值作为其值 。 取一个正常变量int x = 5;
其中x
包含立即值 5
。
另一方面,指针不包含立即值 ,但包含可在内存中找到立即值 (或另一个指针)的地址。 这为您使用指针提供了相当多的灵活性。 就像你可以在x
上使用算术(例如x++;
)增加5
– > 6
,当你将指针递增到一个数组时,指针现在指向数组中的下一个地址。
所以如果你声明了int a[] = {3, 5, 7, 9};
,对于以下内容分配为存储的顺序内存块,您将拥有以下关系:
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
执行相同的操作。 这就是指针算术可以像数组索引一样用来设置,比较,删除数组中的值。 使用指针迭代数组时,通常会声明一个用于迭代目的的指针, 这样就不会丢失内存块的起始地址 。
值得庆幸的是,当指针(或转换的数组)作为参数传递给函数时,函数会接收指针的副本 ,而不是调用函数中指针的原始地址。 您仍然可能需要保存一个包含副本原始地址的指针,但这取决于您在函数中需要执行的操作。
如果你想在function
递增指针中重新实现相同的逻辑而不是递增索引'i'
,那么当你设置默认值时,你将需要处理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++;
)以确保您在if
语句中处理a
中的第二个和第一个字符。 一个例子是:
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'
开头的参数将调用指针使用function:
#include 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
查看function和示例,如果您有任何疑问,请告诉我。 我希望这有帮助。
你的程序有一些未使用的变量。 不要忽略编译器的警告。
这就是我猜你的意思:
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; }
这在function上与:
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; }
它们不一样,你必须用for
替换for
body并使用q
指针修改b
。
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; } }