V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Plumes
V2EX  ›  问与答

C 语言指针问题求解

  •  
  •   Plumes · 2014-11-26 01:31:49 +08:00 · 2306 次点击
    这是一个创建于 3779 天前的主题,其中的信息可能已经有所发展或是发生改变。
    代码如下,使用 gcc 4.9.1 编译:

    #include "stdio.h"
    #include "stdlib.h"
    #define InitSize 100
    typedef struct
    {
    int *data;
    int length;
    } SeqList;
    int InitList (SeqList *L) {
    //SeqList L;
    (*L).data = NULL;
    (*L).data = (int *)malloc(sizeof(int) * InitSize);
    if(!(*L).data) {return (-1);}
    (*L).length = 0;
    return 0;
    }
    int ListInsert (SeqList L, int i, int e) {
    printf("%X\n",&L);
    printf("%d\n", L.length);
    if (i<1 || i>L.length+1) return -1;
    if( i>InitSize ) return -1;
    for (int j=L.length; j>=i; j--) {
    L.data[j] = L.data[j-1];
    }
    L.data[i-1] = e;
    L.length++;
    printf("hi\n");
    return 0;
    }
    int PrintList (SeqList L) {
    printf("%X\n",&L);
    printf("%d\n", L.length);
    for(int j=0; j<L.length; j++) {
    printf("%d, ", L.data[j]);
    }
    return 0;
    }
    int main(void)
    {
    SeqList L;
    InitList(&L);
    printf("m %X\n", &L);
    ListInsert(L, 1, 19);
    ListInsert(L, 2, 11);
    ListInsert(L, 3, 12);
    PrintList(L);
    return 0;
    }
    view raw gistfile1.c hosted with ❤ by GitHub


    这是一个简单的顺序线性表实现,主要有两个个疑问

    1. 为什么创建的线性表 L 在主函数里的地址与传给函数后的地址不同?如图所示
    
    2. 此代码的 ListInsert 函数并不能够实现插入功能,虽然能够将数据项都插入到 L.data 中,但是无法改写 L.length 的值,例如在此代码中的 main 函数中分别执行了三条插入语句,但是打印的时候 L.length 为 0。 而如果在打印函数 PrintList 中将 L.length 值改为 3,则可将插入的数据正常打印出来。
    4 条回复    2014-11-26 08:54:07 +08:00
    canautumn
        1
    canautumn  
       2014-11-26 01:47:37 +08:00
    ListInsert后边是传值传递,不是引用传递。L被复制了一份传进函数了。所以地址不同,而且不会修改主函数里的L。
    canautumn
        2
    canautumn  
       2014-11-26 01:53:40 +08:00   ❤️ 1
    又看了一眼。L复制了一份,所以L本身的地址变了,但是data和length的指针位置直接被复制,是不变的,所以data的值改了。但是L.length++是指针自增1,不是值自增1。应该是*(L.length)++,不过建议一个int不要用指针了。
    bbvps
        3
    bbvps  
       2014-11-26 04:25:41 +08:00
    int ListInsert (SeqList L, int i, int e)--> int ListInsert (SeqList *L, int i, int e) 并修改这个函数的内部,则能够达到你想要的结果。
    pljhonglu
        4
    pljhonglu  
       2014-11-26 08:54:07 +08:00
    ListInsert应该传引用值,要搞清楚值传递与引用传递的区别。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4028 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:28 · PVG 13:28 · LAX 22:28 · JFK 01:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.