阳顺 发表于 2024-8-3 21:24:23

结构体传参 为什么结构体初始化失败呢

#include <stdio.h>
struct Date {               // 申明定义Book结构体的子结构体 Date 变量名为date
                int year;
                int month;
                unsigned int day;
} ;

struct Book {                        //struct申明结构体Book 结构体名称   
                char title ;   char author ;float price ;
                struct Date date;   char publisher;       
} ;

struct Book getinput(struct Book book) ; //申明类型为结构体的函数
struct Book getinput(struct Book book)// 定义结构体函数
{        
       
                book.title = "<<带你学C>>";
                book.author = "小甲鱼";
                returnbook;
}

void printBook(struct Book book);
void printBook(struct Book book)
{
                printf("书名: %s \n",book.title) ;
                //printf("出版日期: %d-%d-%d\n",book.date.year,book.date.month,book.date.day);
}
int main(void){
                struct Book b1;   //
                b1 = getinput(b1);
               
                printBook(b1);
       
                return 0;       
                       
}

jackz007 发表于 2024-8-3 21:24:24

主要有以下 3 个问题:

1、不可以直接向字符串变量赋值:
                book . title = "<<带你学C>>";
                book . author = "小甲鱼";

2、函数的返回值只能是一个数值、指针或布尔值,不可以是结构体。
struct Book getinput(struct Book book)// 定义结构体函数
{         
      
                book.title = "<<带你学C>>";
                book.author = "小甲鱼";
                returnbook;
}

3、当一个函数的声明与该函数的定义出现在同一位置时,没有必要进行声明
struct Book getinput(struct Book book) ; //没有必要进行声明
struct Book getinput(struct Book book)// 定义结构体函数
{         
      
                book.title = "<<带你学C>>";
                book.author = "小甲鱼";
                returnbook;
}

void printBook(struct Book book) ; // 没有必要进行声明
void printBook(struct Book book)
{
                printf("书名: %s \n",book.title) ;
                //printf("出版日期: %d-%d-%d\n",book.date.year,book.date.month,book.date.day);
}
      同时,只有当一个函数的调用位置先于定义位置时,在调用这个函数时才需要对其进行声明,在本例中,函数
struct Book getinput(struct Book book)
{         
      
                book.title = "<<带你学C>>";
                book.author = "小甲鱼";
                returnbook;
}
      和
void printBook(struct Book book)
{
    printf("书名: %s \n", book.title);
    printf("作者: %s \n", book.author);
    printf("价格: %.2f\n", book.price);
    printf("出版日期: %d-%d-%d\n", book.date.year, book.date.month, book.date.day);
}
   的定义位置都在 main() 之前,而这两个函数都是在 main() 中被调用,满足函数定义位置在前,调用位置在后的条件,所以,无需对这两个函数进行声明。
   下面是修改版本,谨供楼主参考
#include <stdio.h>
#include <string.h>

struct Date {
                int year         ;
                int month          ;
                int day            ;
}                                  ;

struct Book {
                char title    ;
                char author    ;
                float price      ;
                struct Date date   ;
                char publisher ;      
}                                  ;

void getinput(struct Book * book , const char * title , const char * author , struct Date date) /* 函数只能返回一个数值或指针,无法返回一个结构,函数声明与定义在一起,没有不要进行声明 */
{         
      
                strcpy(book -> title , title)         ;
                strcpy(book -> author , author)       ;
                book -> date . year= date . year    ;
                book -> date . month = date . month   ;
                book -> date . day   = date . day   ;
}

void printBook(struct Book book)
{
                printf("书名: %s \n" , book . title)                                                          ;
                printf("出版日期: %d-%d-%d\n" , book . date . year , book . date . month , book . date . day) ;
}

int main(void)
{
                struct Book b1                                          ;                                                                              ;
                getinput(& b1 , "<<带你学C>>" , "小甲鱼" , {2024,8,3});                                    ;
                printBook(b1)                                           ;
                return 0                                                ;      
}

FishC 发表于 2024-8-3 21:24:32

看起来你的代码里有几个小问题,让结构体的初始化变得有点“焦头烂额”。让我带你逐个捋一下,看看怎么能让它顺利运行。

### 1. **字符数组的定义问题】
在你的 `Book` 结构体中,`title` 和 `author` 被定义为单个字符(`char`),而你尝试用字符串来初始化它们。C语言中的字符串实际上是一个字符数组。例如,要表示书名和作者,你通常应该使用字符数组:

char title;   // 假设书名最多100个字符
char author;   // 假设作者名最多50个字符

这样才能存放字符串,而不是单个字符。

### 2. **赋值的问题**
你在 `getinput` 函数中尝试用双引号给 `book.title` 赋值,这实际上是错误的。在 C 语言中,字符串需要使用 `strcpy` 函数来复制。例如:

#include <string.h> // 包含这个头文件以使用 strcpy

strcpy(book.title, "书名"); // 用 strcpy 赋值字符串
strcpy(book.author, "小甲鱼");

### 3. **未初始化的日期字段**
虽然你注释掉了日期字段,但如果将来需要用到,记得在 `getinput` 中也要为 `date` 的 `year`, `month`, 和 `day` 赋默认值。

### 纠正后的完整代码:
下面是修复后的代码示例:

#include <stdio.h>
#include <string.h> // 引入字符串处理库

struct Date {               
    int year;
    int month;
    unsigned int day;
};

struct Book {                        
    char title;   // 使用字符数组代替单字符
    char author;
    float price;
    struct Date date;       
    char publisher; // 同样,出版商也可以用字符数组存储
};

struct Book getinput(struct Book book);

struct Book getinput(struct Book book)
{        
    strcpy(book.title, "书名");
    strcpy(book.author, "小甲鱼");
    book.price = 39.99; // 示例价格
    book.date.year = 2023; // 示例日期
    book.date.month = 10;
    book.date.day = 5;
    strcpy(book.publisher, "鱼油出版社");
    return book;
}

void printBook(struct Book book);
void printBook(struct Book book)
{
    printf("书名: %s \n", book.title);
    printf("作者: %s \n", book.author);
    printf("价格: %.2f\n", book.price);
    printf("出版日期: %d-%d-%d\n", book.date.year, book.date.month, book.date.day);
}

int main(void) {
    struct Book b1;

    b1 = getinput(b1);
   
    printBook(b1);       
    return 0;       
}

这样一来,你的结构体就成功初始并赋值了,再也不会因为初始化失败而焦虑了!如果还有其他问题或者不理解的地方,随时可以问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

阳顺 发表于 2024-8-3 23:22:23

jackz007 发表于 2024-8-3 22:32
主要有以下 3 个问题:

1、不可以直接向字符串变量赋值:


第1,3 问题指出的是好,我加以改正
第2个问题,好像小甲鱼课程里说过新的标准支持 结构体函数,2楼改正好了,但结果要想多次使用不理想
你的传参模式很好,只需要在main(),中给多个不一样的参数,可多次使用
要是改为结构体函数,在最后给多个不一样的参数,可多次使用的模式就好了

人造人 发表于 2024-8-4 00:48:56

jackz007 发表于 2024-8-3 22:32
主要有以下 3 个问题:

1、不可以直接向字符串变量赋值:


2、函数的返回值只能是一个数值、指针或布尔值,不可以是结构体。

函数的返回值可以是结构体

sh-5.2$ cat main.c
#include <stdio.h>

struct st {
    int x, y;
};

struct st cxy(int x, int y) {
    return (struct st){x + 1, y + 2};
}

int main(void) {
    struct st xy = cxy(1, 2);
    printf("x: %d, y: %d\n", xy.x, xy.y);
    return 0;
}
sh-5.2$ ./main
x: 2, y: 4
sh-5.2$

三体人的智子 发表于 2024-8-4 07:37:21

本帖最后由 三体人的智子 于 2024-8-4 07:44 编辑

1问题:在结构体成员赋值时,不能直接使用 book.title = "<<带你学 C>>"和 book.author = "小甲鱼"这样的方式。因为 title 和 author 是字符数组,应该使用字符串复制函数如 strcpy 来进行赋值。


2问题:在 printBook函数中,对于字符数组的输出,也应该使用字符串的输出方式。printf("书名:%s\n",book.title)

#include <stdio.h>
#include <string.h>

struct Date {
    int year;
    int month;
    unsigned int day;
};

struct Book {
    char title;
    char author;
    float price;
    struct Date date;
    char publisher;
};

struct Book getinput(struct Book book) {
    strcpy(book.title, "<<带你学 C>>");
    strcpy(book.author, "小甲鱼");
    return book;
}

void printBook(struct Book book) {
    printf("书名: %s \n", book.title);
}

int main(void) {
    struct Book b1;
    b1 = getinput(b1);
    printBook(b1);
    return 0;
}
页: [1]
查看完整版本: 结构体传参 为什么结构体初始化失败呢