注册 登录
编程论坛 C++教室

请问问大侠们,什么原因?

uanjinjun 发布于 2011-09-16 22:59, 429 次点击
#include <stdio.h>
#include <string.h>


#define MAX_LENGTH  60
#define END_OF_ARRAY    '\0'


typedef struct week{
    char name[MAX_LENGTH];
    int  number;
    } Week;


int TestAllocSpace(int num, char **list)
{
    if (num == 0)
        *list = (char *)calloc(1, sizeof(Week));
    else
        *list = (char *)realloc(*list, sizeof(Week)*(num+1));

    return(0);
}


int GetLine(FILE *fp, char string[MAX_LENGTH])
{
  int len;

    while (fgets(string, MAX_LENGTH, fp) != NULL)
    {
        len = strlen(string);
        if (len > 1)
        {
            string[len-1] = END_OF_ARRAY;
            return (0);
        }
    }

  return (-1);
}
   

int main(int argc, char *argv[])
{
  char line[MAX_LENGTH];
  Week *list=NULL, *p;
  int i, num=0;
  FILE  *fp;
 
    if( argc < 2 )
        exit(-1);

    fp = fopen( argv[1], "r");
    if( fp == NULL )
        exit(-1);

    while ( !GetLine(fp, line) )
    {
        TestAllocSpace(num, &list);
        strcpy(list[num].name, line);
        
        p = &(list[num]);
        p->number = num;
        
        num++;
    }


    for(i = num-1; i >= 0; i--)
        printf("%d) %s\n", list[i].number, list[i].name);

    free(list);

    fclose(fp);
   
  return(0);
}
该程序中子函数TestAllocSpace(int num, char **list)中第二个形参为char型,但主函数中调用该子函数时传递的参数为我week结构类型的,该程序可以运行成功,请问问大侠们,什么原因?
4 回复
#2
tisyang2011-09-17 10:03
list 为 指向 Week 类型的指针类型,
&list 为 list 这个指针的地址,就是说传递的是一个指向 list 的指针,也就是个二级指针

TestAllocSpace(int num, char **list) 第二个形参类型为 指向 char * 的指针,就是指向 char 的二级指针。

需求二级指针做形参的函数一般都会修改传入的 二级指针实参,目的就是修改传入的指针的值。 在这里就是为了修改 list 这个指针。
#3
uanjinjun2011-09-17 14:48
谢谢2楼的回答,但是C语言教材上说过函数的形参和实参的数据类型必须一致,形参中是char型,实参中是Week型,不一致呀?
#4
玩出来的代码2011-09-18 10:56
complier、、
#5
tisyang2011-09-19 09:13
回复 3楼 uanjinjun
C语言规定了 sizeof(char) 必须为1,分配内存的时候基础单位是以 char 大小来分配,
分配了一段内存后,很自然的将内存首地址赋给 char 指针。
因为指针的作用以及指针的本身大小是一致的,所以所有类型的普通指针之间可以互相转换的,
函数的第二个形参是一个 指向 char 指针的指针类型,不是 char 类型。
实参是一个 指向 Week 指针的指针类型,不是你所说的 Week 类型。
函数调用前会强制转换实参  Week ** 类型到 char ** 类型。这个转换有可能编译器会自己去做,但是也有可能需要用户去强制转换。
1