C语言实现数据结构的两种声明结构体的方式有什么区别

数据结构 顺序表结构的数据结构体

typedef struct
{
    ElemType data[MAXSIZE];
    int length;
}SqList;

第一种声明方式

SqList SeqlistInsert(SqList L, int i, ElemType x)

第二种声明方式

SqList SeqlistInsert(SqList *L, int i, ElemType x)

加星号 " * "和不加*有啥区别,主要是结构体加了* 号如何看这个数据和操作的问题

回复
阅读 4.3k
5 个回答

C语言函数传递参数是值传递,也就是会将实参复制一份,然后再给函数使用。
比如这个函数,

SqList SeqlistInsert(SqList L, int i, ElemType x)
{
...
}

SqList S1;
ElemType E1;
...
SeqlistInsert(S1, 1, E1);
...

S1会被复制一份,然后传给SeqlistInsert()函数,如果SeqlistInsert()函数尝试对S1进行修改,比如SeqlistInsert(S1, 1, E1)中有这个语句

S1.length = 3;

这里修改的并不是我们最开始定义的S1(SqList S1;处定义的S1),而是复制后的S1,这么做的结果就是我们没有办法修改之前定义的S1。

另一种形式就不一样了,

SqList SeqlistInsert(SqList *L, int i, ElemType x)
{
...
}

SqList *S1;
ElemType E1;
...
SeqlistInsert(S1, 1, E1);

这里S1是指在,它的值就是S1所在的内存地址。我们如果想修改S1的值,我们只需要添加

S1->length = 3;

就可以修改之前定义的S1了。因为虽然传入SeqlistInsert()函数的也是S1的复制体,但它们的值都是S1的内存地址,所以我们可以用这种方式修改S1中元素的值。

如果还有不懂,请百度"C语言函数值传递"。

一个是传指针一个是传副本,通常不会传副本,一是大量占用内存二是对对象修改不灵活。建议你找个c基础的书开始看。

这个是C的语法问题,跟结构体没什么关系。

这个区别啊,其实挺简单的,SqList *表示结构体指针

访问区别 :结构体指针访问结构体成员要 用-> 访问符号,结构体变量的话,用.访问其成员

函数传参区别: 传了一个指针过去,那么在函数内部修改的时候,是通过指针寻找真正的内存空间直接修改主函数的结构体成员数据,而单纯的传入结构体变量到一个函数内部,那么就是值传递。

动态开辟内存区别:使用指针,可以动态的开辟多个结构体变量的大小。

下面示例

#include <stdio.h>
typedef struct
{
    int a;
    char b[20];
}NewStruct;

void changeData(NewStruct Tab){
    Tab.a = 600;
    Tab.b[0] = 's';    
}

int main()
{
    int i=0;
    NewStruct Tab;
    Tab.a = 30;
    for(;i<20;i++)
    {
        Tab.b[i] = 'a';
    }
    printf("%d,%s\n",Tab.a,Tab.b);
    changeData(Tab);
    printf("%d,%s",Tab.a,Tab.b);
} 

描述有误,怎么能说加不加星号有什么区别?加不加星号类型都不同了,还用同一个变量名,有误导嫌疑。我觉得如果谁写代码,对于同一类型的对象、指针,在不同的函数中使用一样的变量名,就有一定误导性。我觉得首先从变量命名上就要保持区别。比如char cchar *pSqList slSqList *psl,加上p前缀表示其是指针类型。

typedef struct {
    ElemType data[MAXSIZE];
    int length;
} SqList;

int init1(SqList sl)
{
    // 参数 sl (SqList 对象),是传入参数的拷贝,对该副本进行修改:
    memset(sl.data, 0, sizeof(sl.data));
    sl.length = 0;
    // sl 对象是一个临时副本,离开函数失效。没有影响到原来的参数值。
}

int init2(SqList *psl)
{
    // 参数 psl (指向 SqList 对象) 是指向传入参数的指针,通过指针修改外部对象:
    memset(psl->data, 0, sizeof(psl->data));
    psl->data = 0;
    // psl 指针也是一个临时副本,离开函数也失效。但间接影响了它指向的对象。
}

int main(void)
{
    SqList sl;
    init1(sl);  // sl 自身拷贝一份传入,sl 原值不受影响。
    init2(&sl); // sl 的地址传入,通过地址修改 sl 的值。
    return 0;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏