对不起,另一个C指针问题..我有一个函数func()对数组进行排序,然后得到最大和最小的整数.我试图将它们放在main()中的指针变量中,但这些值只在func()函数内部正确.我不明白为什么:(
#include <stdio.h>
void func(int arr[], int *s, int *l, int n){
int i = 1;
for(; i < n; i++){
int temp = arr[i];
int n = i;
while( n > 0 && arr[n-1] > temp){
arr[n] = arr[n-1];
n--;
}
arr[n] = temp;
}
l = &arr[n-1];
s = &arr[0];\
printf("%d %d\n",*l,*s);
}
int main(void){
int arr[] = {1,2,9,3,58,21,4};
int *s, *l;
int size = 7;
func(arr,s,l,size);
printf("%d %d\n",*l,*s);
}
Run Code Online (Sandbox Code Playgroud)
将指针作为参数传递给C中的函数时,会生成指针的副本.因此,更改指针的值在该函数之外没有任何影响.但是,更改指针引用的内存中的值将随时随地生效.在您的情况下,您需要这样做:
void func(int arr[], int *s, int *l, int n){
// sorting code..
// l = &arr[n-1]; WRONG - these change the value of the pointer,
//s = &arr[0];\ without changing the value of the memory they reference
*l = arr[n-1]; // CORRECT - changes the value at the referenced memory
*s = arr[0];
printf("%d %d\n",*l,*s);
}
Run Code Online (Sandbox Code Playgroud)
当然,你使用指针的main
方式也是不正确的; 它们未初始化并可能导致分段错误.由于似乎没有理由int*
在普通int
变量上使用实际变量,我们可以采用另一种方法来"通过引用"传递它们:
int main(void){
int arr[] = {1,2,9,3,58,21,4};
// int *s, *l; WRONG - we don't need pointers, we need to pass regular ints
int s, l;
int size = 7;
// Get the address of our variables with the address-of (&) operator
// This effectively creates int* variables out of our int variables
func(arr, &s, &l,size);
printf("%d %d\n",*l,*s);
}
Run Code Online (Sandbox Code Playgroud)
请注意,这里的术语"通过引用"在短语的真正意义上是不正确的,因为您仍然收到与该变量关联的地址的副本.大多数语言通过消除这种区别提供真正的副参考教师,并且只允许您访问变量及其值,而复制程序有点看不到程序员.你可以认为这为"参照相对于l
和s
里面main
",在这个意义上,它们的值可以改变由于调用的函数.
如果要更改指针变量所指向的内容,则需要传递指针变量的地址,否则将在函数内部更改指针变量的副本(这就是为什么它在函数中正确的原因):
void func(int arr[], int** s, int** l, int n){
/* snip */
*l = &arr[n-1];
*s = &arr[0];
}
func(arr, &s, &l, size);
Run Code Online (Sandbox Code Playgroud)
这将离开s
并l
指向数组的元素arr
。如果你只想要整数的值,那么另一种方法是定义int
变量main()
并将它们的地址传递给func()
数组并从数组中复制相关值:
void func(int arr[], int* s, int* l, int n){
/* snip */
*l = arr[n-1];
*s = arr[0];
}
int s, l;
func(arr, &s, &l, size);
Run Code Online (Sandbox Code Playgroud)
请参阅C 常见问题解答中的此问题。