更好地理解 C 指针

Understanding C Pointers better

提问人:Sanku 提问时间:11/17/2023 最后编辑:Sanku 更新时间:11/17/2023 访问量:186

问:

我试图理解下面的代码,但我觉得我错过了一些东西:

假设我有一个如下结构:

struct example
{ 
int a; 
int b; 
int c; 
int d; 
};

现在我创建一个类型为 example 的数组,如下所示:

example arr[4] = {0};

现在,如果我想将这个数组传递给另一个函数,比如 func1,它反过来调用另一个函数 func2,它实际上修改了 arr,

int main(){ 
... 
... 
func1(arr); 
}

void func1(arr){
 func2(arr)
}
void func2(arr)
{  
// arr gets modified here 
}

我理解实现这一点的一种方法如下:

int main()
{    
example *arrp = arr;    
func1(&arrp); 
}

void func1(example **arr)
{   
func2(*arr); 
}

void func2(example *arr)
{    
arr.a = 1;   
 ....    
}

有没有更好的方法可以做到这一点,而不使用额外的变量 arrp?

编辑1:

#include<stdio.h>
#include<stdlib.h>

void assign(int **tags2){
    *tags2 = (int*)malloc(3 * sizeof(int));

    *tags2[0] = 2;
}

void second(int *tags, int * tags_2){
    tags[0] = tags_2[0];
}

void first(int *tags){
    
    int *tags2 = NULL;
    assign(&tags2);
    second(tags, tags2);

    free(tags2);
}



int main(){


   int tags[3] = {0};

   first(tags);

   printf("Hello %d", tags[0]);

    return 0;
}
C 指针

评论

3赞 chux - Reinstate Monica 11/17/2023
example arr[4] = {0};-->在哪里定义?您使用的是 C++ 编译器吗?example
0赞 HolyBlackCat 11/17/2023
您的新代码看起来已经是最佳的了。我看不出有什么可以简化的。

答:

0赞 Alex Ixeras 11/17/2023 #1

在 C 中,数组的名称可以用作指向其第一个元素的指针。这意味着当你将数组传递给一个函数时,你实际传递的是指向数组第一个元素的指针。因此,您不需要像 main 函数那样使用额外的指针变量。arrp

你能做的就是这个。

  1. 定义结构
    struct example { 
        int a; 
        int b; 
        int c; 
        int d; 
    };
  1. 将数组直接传递给 func1

您可以直接将数组传递给,因为在函数调用中,数组名称 隐式转换为指向数组第一个元素的指针。当你将数组传递给一个函数时,实际传递的不是整个数组,而是指向其第一个元素的指针。这种行为通常称为“阵列衰减”。func1arr

int main() {    
    struct example arr[4] = {0};
    func1(arr); 
    ....
}
  1. 修改函数签名

func1应该接受一个指针(这是数组名称在传递时衰减成的指针),并且应该做同样的事情。struct examplearrfunc2

void func1(struct example *arr) {
    func2(arr);
}

void func2(struct example *arr) {
    arr[0].a = 1; // Modify the first struct in the array
    // Other modifications...
}

在此设置中,接收指向数组第一个元素的指针,并将该指针传递给 。在里面,您可以根据需要修改数组元素。由于 in 是指向 中的数组的指针,因此您在 中所做的任何修改都将反映在 中的原始数组中。func1func2func2arrfunc2mainfunc2main

请记住,在 C 语言中,数组和指针密切相关,但并不完全相同!当数组传递给函数时,它会衰减为指向其第一个元素的指针,但它不具有指针的所有属性,例如可赋值。这有帮助吗?

评论

3赞 chux - Reinstate Monica 11/17/2023
“由于数组名称 arr 本质上是指向数组第一个元素的指针”,因此最好是“因为数组名称在函数调用中转换为指向数组第一个元素的指针。arr
1赞 HolyBlackCat 11/17/2023
试图为“数组”和“数组的名称”赋予不同的含义没有多大意义。最好说在某些情况下,数组可以隐式转换为指针。
0赞 Alex Ixeras 11/17/2023
@chux-ReinstateMonica 是的,您的改写更准确,技术更精确。谢谢。
2赞 Alex Ixeras 11/17/2023
@HolyBlackCat 谢谢,同意。我应该提到,这种转换是隐式的,当数组在需要指针的上下文中使用时会自动发生,例如函数调用。我现在已经说得更清楚了。
0赞 Andrew Henle 11/17/2023
@chux-ReinstateMonica 最好是“因为数组名称 arr 在函数调用中转换为指向数组第一个元素的指针。我想说 Alex 是对的,因为转换不仅限于函数调用,它适用于每个带有数组的表达式:“类型为”数组类型“的表达式被转换为类型为”指向类型指针“的表达式,该表达式指向数组对象的初始元素,而不是左值。 就是一个例子。struct example *ptr = arr;