提问人:Leila Jones 提问时间:9/18/2023 最后编辑:Leila Jones 更新时间:9/18/2023 访问量:84
在 C 语言中取消引用指针时遇到困难
Having difficulties dereferencing a pointer in C
问:
我的任务是编写一个程序,询问用户他们必须花多少钱,然后询问用户他们想购买多少张票。我必须有一个 main() 函数和一个 PurchaseTickets() 函数。我是指针的新手,并且对如何使用它们来分配局部变量以及将这些局部变量用于计算感到非常困惑。我能深入了解我哪里出了问题,以及如何将其变成一个可用的程序吗?
编辑:必须有两个功能:主要和购买门票。使用变量 remaining cash 的指针是必要的,如果用户没有足够的钱来购买门票,程序必须返回 0。
#include <stdio.h>
#define ADULT_TICKET_PRICE 69.00 //define constants
#define CHILD_TICKET_PRICE 35.00
int PurchaseTickets(double *pRemainingCash, int adultTickets, int childTickets); //declare function PurchaseTickets()
int main(void)
{
double funds;
int childTickets;
int adultTickets;
printf("How much money do you have to purchase tickets?\n");
if(scanf("%lf", &funds) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
printf("How many child tickets would you like to purchase?\n");
if(scanf("%d", &childTickets) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
printf("How many adult tickets would you like to purchase?\n");
if(scanf("%d", &adultTickets) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
double *pfunds = &funds;
PurchaseTickets(pfunds, adultTickets, childTickets);
return 0;
}
/*****************************************************************************************
*
* Function: PurchaseTickets()
*
* Parameters:
*
* pRemainingCash - points to a variable containing the amt of cash from user
* adultTickets - specifies the number of adult tickets the user wants to buy
* childTickets - specifies the number of child tickets the user wants to buy
*
* Description:
*
* The function will determind if the user has enough money to purchase the
* specified number of tickets. If they do, the function deducts the proper funds
* from their remaining cash and returns the total number of tickets purchased.
* if they do not the function returns 0.
*
*****************************************************************************************/
int PurchaseTickets(double *pRemainingCash, int adultTickets, int childTickets)
{
double adultCost = (adultTickets * ADULT_TICKET_PRICE);
double childCost = (childTickets * CHILD_TICKET_PRICE);
double totalCost = adultCost + childCost;
int totalTickets = adultTickets + childTickets;
double remainingCash = *pRemainingCash;
pRemainingCash = &remainingCash;
pRemainingCash = remainingCash - totalCost;
if (*pRemainingCash >= totalCost)
{
printf("You have purchased %d tickets, and you have %.2f remaining.",totalTickets, pRemainingCash);
}
else
{
printf("You do not have enough money to purchase the tickets.");
return 0;
}
return 1;
}
答:
我查看了您的代码,从我所看到的所需解决方案来看,该程序目的的上下文确实不需要指针。首先,由于“PurchaseTickets”函数并没有真正返回任何所需的信息,因此使用void返回条目对其进行设置更有意义。其次,由于函数所需的输入变量可以全部作为值传递,因此实际上不需要发送指针引用。
为了尽量减少对代码的最小更改,可以在函数中注释掉以下语句以及重构“printf”语句。
//double remainingCash = *pRemainingCash; // Not needed
//pRemainingCash = &remainingCash;
//pRemainingCash = remainingCash - totalCost;
if (*pRemainingCash >= totalCost)
{
printf("You have purchased %d tickets, and you have %.2f remaining.",totalTickets, *pRemainingCash - totalCost); // Note remainder calculation
}
这在终端上产生了以下测试输出。
craig@Vera:~/C_Programs/Console/TicketPurchase/bin/Release$ ./TicketPurchase
How much money do you have to purchase tickets?
800
How many child tickets would you like to purchase?
4
How many adult tickets would you like to purchase?
4
You have purchased 8 tickets, and you have 384.00 remaining.
注意代码的观察结果并简化事情,以下是程序的重构版本。
#include <stdio.h>
#define ADULT_TICKET_PRICE 69.00 //define constants
#define CHILD_TICKET_PRICE 35.00
void PurchaseTickets(double pRemainingCash, int adultTickets, int childTickets); //declare function PurchaseTickets()
int main(void)
{
double funds;
int childTickets;
int adultTickets;
printf("How much money do you have to purchase tickets? ");
if(scanf("%lf", &funds) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
printf("How many child tickets would you like to purchase? ");
if(scanf("%d", &childTickets) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
printf("How many adult tickets would you like to purchase? ");
if(scanf("%d", &adultTickets) != 1) //check for errors in user input
{
printf("Invalid input, exiting program.\n");
return 1; //will exit program if invalid characters are entered
}
PurchaseTickets(funds, adultTickets, childTickets);
return 0;
}
/*****************************************************************************************
*
* Function: PurchaseTickets()
*
* Parameters:
*
* pRemainingCash - points to a variable containing the amt of cash from user
* adultTickets - specifies the number of adult tickets the user wants to buy
* childTickets - specifies the number of child tickets the user wants to buy
*
* Description:
*
* The function will determind if the user has enough money to purchase the
* specified number of tickets. If they do, the function deducts the proper funds
* from their remaining cash and returns the total number of tickets purchased.
* if they do not the function returns 0.
*
*****************************************************************************************/
void PurchaseTickets(double pRemainingCash, int adultTickets, int childTickets)
{
double adultCost = (adultTickets * ADULT_TICKET_PRICE);
double childCost = (childTickets * CHILD_TICKET_PRICE);
double totalCost = adultCost + childCost;
int totalTickets = adultTickets + childTickets;
pRemainingCash -= totalCost;
if (pRemainingCash >= 0.00)
{
printf("You have purchased %d tickets, and you have %.2f remaining.\n",totalTickets, pRemainingCash);
}
else
{
printf("You do not have enough money to purchase the tickets.\n");
}
return;
}
请注意以下改进:
- “PurchaseTickets”函数的返回值已更改为“void”,因为似乎没有使用整数返回值。
- 所有变量都作为值传递,而不是使用任何变量指针。
- 删除了不需要的变量,以简化计算和比较。
通过这些改进,以下是对程序和购票功能的一系列额外测试。
craig@Vera:~/C_Programs/Console/TicketPurchase/bin/Release$ ./TicketPurchase
How much money do you have to purchase tickets? 300.00
How many child tickets would you like to purchase? 4
How many adult tickets would you like to purchase? 4
You do not have enough money to purchase the tickets.
craig@Vera:~/C_Programs/Console/TicketPurchase/bin/Release$ ./TicketPurchase
How much money do you have to purchase tickets? 600
How many child tickets would you like to purchase? 4
How many adult tickets would you like to purchase? 4
You have purchased 8 tickets, and you have 184.00 remaining.
总而言之,在函数中传递变量地址代替变量值是有正当理由的,但人们应该始终了解函数的上下文,以确定是否有必要这样做。寻找有关函数定义的其他教程,了解指针何时有益可能是明智的。
评论
这是一团糟。在不重复@NoDakker的评论的情况下,下面是代码的缩写版本,显示了所需的操作。请注意,一些变量已被重命名(并删除了注释)以提高清晰度。
// heading stuff omitted for brevity
int main(void)
{
double funds;
int childTickets;
int adultTickets;
/* Get funds */ // omitted for brevity
/* Get # of Child tickets */
/* Get # of Adult tickets */
int totTckts = PurchaseTickets( &funds, adultTickets, childTickets );
// Notice that the function performs its task.
// Reporting those results belongs in the calling function
if( totTckts )
printf( "%d tickets, and you have %.2f remaining.", totTckts, funds );
else
printf( "Insufficient funds to purchase those tickets." );
return 0;
}
int PurchaseTickets( double *pFunds, int nAdult, int nChild )
{
double Cost
= (nAdult * ADULT_TICKET_PRICE)
+ (nChild * CHILD_TICKET_PRICE);
if( *pFunds < Cost ) // Insufficient available funds?
return 0; // no show
*pFunds -= Cost; // subtract cost from "double funds;" variable in main()
return nAdult + nChild; // return # of purchased tickets
}
评论
在函数中存在一些问题。PurchaseTickets
double remainingCash = *pRemainingCash;
pRemainingCash = &remainingCash;
此代码创建值的副本,指向本地副本,然后将其指向本地副本。此代码是正确的,但似乎不是正确的做法。pRemainingCash
pRemainingCash = remainingCash - totalCost;
这是由于语法而遇到错误的地方。它试图将浮点值分配给指针,而不是指针指向的内容。为此,您需要*pRemainingCash = remainingCash - totalCost;
这将解决错误,但不能解决问题,因为它正在修改本地副本而不是传入的值。
另一个问题是,在减去成本之前,您应该检查他们是否买得起门票。我希望如果成本超过可用资金,您将保持可用资金不变。
下面是一个清理后的版本:
int PurchaseTickets(double *pRemainingCash, int adultTickets, int childTickets)
{
double adultCost = (adultTickets * ADULT_TICKET_PRICE);
double childCost = (childTickets * CHILD_TICKET_PRICE);
double totalCost = adultCost + childCost;
int totalTickets = adultTickets + childTickets;
if (*pRemainingCash >= totalCost)
{
// Subtract cost here
*pRemainingCash -= totalCost;
// Note *pRemainingCash in the next line.
// You need to dereference to obtain the value pointed at.
printf("You have purchased %d tickets, and you have %.2f remaining.",
totalTickets, *pRemainingCash);
// Return success
return totalTickets;
}
// This code won't be reached in the success case because of the return.
// Removing the else avoids the possibility of the compiler warning that
// all paths do not return a value.
printf("You do not have enough money to purchase the tickets.");
return 0;
}
中的另一个小建议。main
而不是仅仅调用函数double *pfunds = &funds;
PurchaseTickets(&funds, adultTickets, childTickets);
你所拥有的是有效的,但我认为最好不要为此创建一个额外的变量。如果之后有更多的代码,可能会混淆使用哪一个。
上一个:使用 C 返回数组
下一个:将指针参数传递给函数?[复制]
评论