这是一个计算所有月订阅总额的程序。但问题是netflixBill,disneyBill等的值在函数调用时为0,所以总额只是struct元素。我已经尝试了所有我知道的方法,但我不明白为什么它不起作用。enter image description here
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct Subscription {
char name[100];
float price;
};
int check_login(char *, char *);
void askSubscriptionQuestions(bool *, bool *, bool *, bool *);
struct Subscription ask_subscription();
float total_price(struct Subscription subscriptions[], int num_subscriptions, float netflixBill, float disneyBill, float hboBill, float spotifyBill);
struct Subscription ask_subscription(void) {
struct Subscription subscription;
printf("What is the name of the subscription? ");
scanf("%s", subscription.name);
printf("How much do you pay every month for it? ");
scanf("%f", &subscription.price);
return subscription;
}
int main()
{
float netflixBill = 0.0f, disneyBill = 0.0f, hboBill = 0.0f, spotifyBill = 0.0f;
char id[20];
char password[20];
bool hasPassed;
bool hasNetflix;
bool hasDisneyPlus;
bool hasHBO;
bool hasSpotify;
char response;
struct Subscription subscriptions[100];
int num_subscriptions = 0;
while (1) {
printf("Enter your ID: ");
scanf("%s", id);
printf("Enter your password: ");
scanf("%s", password);
if (check_login(id, password)) {
printf("Access granted.\n");
hasPassed = true;
break;
} else {
hasPassed = false;
printf("Access denied.\n");
}
}
printf("Do you have any monthly subscriptions? (y/n) ");
char c;
while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
scanf("%s", &c);
if (c != 'y' && c != 'Y' && c != 'n' && c != 'N'){
printf("Invalid input. Please enter 'y' or 'n': ");
}
}
printf("%f %f %f %f", netflixBill, disneyBill, hboBill, spotifyBill);
if (c == 'y' || c == 'Y') {
askSubscriptionQuestions(&hasNetflix, &hasDisneyPlus, &hasHBO, &hasSpotify);
} else if (c == 'n' || c == 'N') {
printf("OK, thank you for your answer.\n");
}printf("%f %f %f %f", netflixBill, disneyBill, hboBill, spotifyBill);
printf("Do you have any other monthly subscriptions (Y/N)? ex: YT Premium, iCloud, etc.\n");
scanf("%s", &response);
while (response == 'Y' || response == 'y') {
subscriptions[num_subscriptions] = ask_subscription();
num_subscriptions++;
printf("Do you have any other monthly subscriptions (Y/N)? ");
scanf("%s", &response);
}
if (num_subscriptions > 0) {
printf("Your subscriptions are:\n");
for (int i = 0; i < num_subscriptions; i++) {
printf("- %s: $%.2f\n", subscriptions[i].name, subscriptions[i].price);
}
} else {
printf("You do not have any other monthly subscriptions.\n");
}
float total = total_price(subscriptions, num_subscriptions, netflixBill, disneyBill, hboBill, spotifyBill);
printf("The total cost of all your subscriptions is $%.2f\n", total);
return 0;
}
int check_login(char *id, char *password) {
if (strcmp(id, "admin") == 0 && strcmp(password, "pass123") == 0) {
return 1;
} else {
return 0;
}
}
void askSubscriptionQuestions(bool *hasNetflix, bool *hasDisneyPlus, bool *hasHBO, bool *hasSpotify) {
char c;
int netflixPlan, spotifyPlan;
float netflixBill = 0.0f, disneyBill = 0.0f, hboBill = 0.0f, spotifyBill = 0.0f;
printf("Do you have a subscription to Netflix? (y/n) ");
scanf("%s", &c);
if (c == 'y' || c == 'Y') {
*hasNetflix = true;
printf("Which monthly plan do you have? Here is a list: \n");
printf("\t 1 for Minimum = 7.99$/month\n");
printf("\t 2 for Standard = 9.99$/month\n");
printf("\t 3 for Premium = 11.99/month\n");
scanf("%d", &netflixPlan);
if(netflixPlan == 1){
netflixBill = 7.99;
}
else if(netflixPlan == 2){
netflixBill = 9.99;
}
else
netflixBill = 11.99;
} else {
*hasNetflix = false;
printf("You don't have a Netflix subscription. \n");
}
printf("Do you have a subscription to Disney+? (y/n)\n ");
scanf("%s", &c);
if (c == 'y' || c == 'Y') {
*hasDisneyPlus = true;
disneyBill = 5.99;
printf("The subscription for Disney+ is 5.99$/month.\n");
} else {
*hasDisneyPlus = false;
printf("You don't have a Disney+ subscription. \n");
}
printf("Do you have a subscription to HBO? (y/n)\n ");
scanf("%s", &c);
if (c == 'y' || c == 'Y') {
*hasHBO = true;
hboBill = 4.99;
printf("The subscription for HBO is 4.99$/month.\n");
} else {
*hasHBO = false;
*hasHBO = false;
printf("You don't have a HBO subscription. \n");
}
printf("Do you have a subscription to Spotify? (y/n) ");
scanf("%s", &c);
if (c == 'y' || c == 'Y') {
*hasSpotify = true;
printf("Which monthly plan do you have? Here is a list: \n");
printf("\t 1 for Premium = 4.99$/month\n");
printf("\t 2 for Premium for students = 2.49$/month\n");
scanf("%d", &spotifyPlan);
if(spotifyPlan == 1)
spotifyBill = 4.99;
else
spotifyBill = 2.49;
} else {
printf("You don't have a Spotify subscription. \n");
*hasSpotify = false;
}
}
float total_price(struct Subscription subscriptions[], int num_subscriptions, float netflixBill, float disneyBill, float hboBill, float spotifyBill) {
float total = netflixBill + disneyBill + hboBill + spotifyBill;
for (int i = 0; i < num_subscriptions; i++) {
total += subscriptions[i].price;
}
return total;
}
我试过使用指针(idk如果我做得对的话).试过使用chatgpt但是它也不知道问题是什么.
2条答案
按热度按时间lvjbypge1#
未初始化的变量:
此循环调用未定义的行为,因为
c
从未初始化。格式说明符不正确:
对
scanf
的调用也会调用Undefined Behaviour,因为c
已声明为char
,并且%s
说明符用于字符串。我数了
7
个你犯同样错误的例子。一旦抽象状态机到达未定义状态,就不能进一步假设程序的执行是否继续。
变量范围:
在
main
中定义的变量仅对main
是局部的。您在askSubcriptionQuestions
中声明了spotifyBill ...
的另一个示例,这些变量仅对askSubcriptionQuestions
是局部的。它们在main
中不可见,并且在main
中声明的变量在其他函数中不可见。VLA
或临时对象,否则自动变量的生存期与其定义块的执行相对应如果你想使用main中声明的相同变量,你必须将它们传递给其他函数
by reference
,这样,对这些变量所做的更改将是永久性的。yebdmbv42#
您的问题与变量的作用域有关。
实际上,你在函数 askSubscriptionQuestions 中使用了局部变量来赋值,但是当你终止这个函数时,所有的局部变量都丢失了。不要因为你命名它们的方式和main中声明的变量一样而感到困惑。这并不重要,重要的是变量的作用域。
一旦你在main中声明了你的 netflixBill 变量,你需要通过引用传递它,也就是说,传递变量的地址而不是值。你可以使用“&"来完成这一操作。这样,如果你在函数内部正确地修改了这个地址所指向的值,当它完成时,你不会丢失变量的值。
您需要进行以下几项更改:
无效提问订阅问题(...,netflixBill, 迪斯尼Bill,hboBill, spotify Bill)
询问订阅问题(...,&netflixBill,&迪斯尼Bill,&hboBill,& spotify Bill)
我强烈建议你学习和理解通过引用和通过值传递变量到函数的概念,这是C语言中必不可少的编码。