So, I am led to believe by my professor that when declaring the size of an array, it is best to use #define vs. just declaring it as a normal integer. Is this correct?
If so, why?
Also, if this is correct, what am I doing wrong? When I try to do this I get an message:
error: expected ';', ',' or ')' before numeric constant
every time I call the array. The code works if I just initialize it as an integer.
The definition and usage can be seen in the following code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define handsize 5
#define size 52
// Create function prototypes
void create_deck (int deck[]);
void shuffle_deck (int size, int deck[]);
void display_card (int card);
void display_hand (int size, int hand[]);
int popCard (int *size, int deck[]);
int findScore (int size, int hand[]);
int main()
{
// declare/ initialize variables
int c, d, p, win = 0, lose = 0 , tie = 0, /*handsize = 0, size = 52,*/ deck[size], hand[handsize], dealer[handsize];
char play;
srand(time(NULL)); // attach random number generator to time function for truly random variables
// explain program to user and ask if they want to play
printf("This program is a card game that adds the values of all the\n");
printf("cards in the players hand, and the computers hand. The highest hand wins.\n");
printf("Would you like to play? Please press 'y' for yes, any other key for no.\n");
scanf("%c", &play); // if the user wants to play, continue the program
// while loop that continues as long as the user wants to play
while (play == 'y'){
// call functions to create and shuffle the deck
create_deck(deck);
shuffle_deck (size, deck);
// for loop that calls the popCard function to deal the top card in the deck
for (c = 0; c < 5; c++){
hand[c] = popCard (&size, deck); // player gets a card
dealer[c] = popCard (&size, deck); // computer gets a card
handsize++;
// call the display_hand function to display the individual cards in the players hand
printf("\nYour hand consists of:\n");
display_hand (handsize, hand);
// call the display_hand function to display the individual cards in the dealers hand
printf("Dealer hand consists of:\n");
display_hand (handsize, dealer);
}
// call the findScore function for both the user and the computer
p = findScore (handsize, hand);
d = findScore (handsize, dealer);
// show the value of the user and computers hands
printf("\nThe value of your hand is %i\n", p);
printf("\nThe value of the dealers hand is %i\n", d);
// if statements that keep track of wins, losses and ties
if (p > d)
win++;
if (p == d)
tie++;
if (p < d)
lose++;
// show number of times player has won, lost, tied. Then ask to play again
printf("You have won %i times, tied %i times, and lost %i times\n", win, tie, lose);
printf("\nWould you like to play again?\n");
fflush(stdin); // flush the input buffer to stop false readings
scanf("%c", &play); // read the user input to determine if they want to play again
}
printf("Goodbye");
return 0;
**I hope this is what you wanted
Symbolic constants (either #define or actual constants) are generally preferred.
What happens, for example, when your code is peppered with the value 1440 but you use that number for both twips per inch and kilobytes per floppy (very much showing my age here)?
Then all of a sudden your floppies become 2.88M. You then have to go through all your code looking for 1440 and figuring out if it meant the twips or kilobytes version, and changing the relevant ones. So not only do you have to make the change in multiple places (bad enough), you may also have to figure out whether the change you be made at each place.
Had you instead done:
#define TWIPS_PER_INCH 1440
#define KB_PER_FLOPPY 1440
and then peppered your code with the symbolic names, you could have then just changed one line, without too much thinking or analysis required.
There's a school of thought that any number other than zero or one (and possibly negative one) should have a symbolic constant of some sort. Just make sure you don't make the mistake of doing:
#define FOURTEEN_HUNDRED_AND_FORTY 1440
like one of my minions once tried. I had endless fun trying to explain why that was a bad idea :-)
As to your error, it's certainly possible to declare an array with a preprocessor constant as shown below:
#include <stdio.h>
#include <string.h>
#define VAR 42
int main (void) {
char xyzzy[VAR];
strcpy (xyzzy, "pax is awesome");
puts (xyzzy);
return 0;
}
However, consider the following lines in your code:
#define size 52
void shuffle_deck (int size, int deck[]);
void display_hand (int size, int hand[]);
int popCard (int *size, int deck[]);
int findScore (int size, int hand[]);
hand[c] = popCard (&size, deck);
// and possibly many others.
Because preprocessing is a textual substitution done early in the compilation process, those lines following the first are going to become:
void shuffle_deck (int 52, int deck[]);
void display_hand (int 52, int hand[]);
int popCard (int *52, int deck[]);
int findScore (int 52, int hand[]);
hand[c] = popCard (&52, deck);
and they will cause all sorts of problems, among them that 52 is not a valid variable name in a function prototype, and that you cannot take the address of an integer literal in C because it has no address.
In order to fix this, you define the initial size as a constant:
#define INIT_SZ 52
and use that to set the initial value of a variable size which you can later change, something like:
void doSomethingThatChangesSize (int *pSize) {
(*pSize) += 42;
}
int size = INIT_SZ; // this is the only way you use INIT_SZ
:
doSomethingThatChanges (&size);
Related
I need some help with a program I've been making for the university. Inside this program, it must be a function that must increase the price of a type of product according to a value given by the user. Fine, I've written the following function:
void increase_price(struct reg products[SIZE], int count){
int i;
float increase, perc;
char option;
printf("Type of product: ");
fflush(stdin); scanf("%c", &option);
printf("\nThe increase percentage: ");
fflush(stdin); scanf("%f", &perc);
for(i=0; i<count; i++){
if(products[i].type == option){
increase = products[i].price * (perc/100);
products[i].price += increase;
}
}
}// Fim increase_price()
The problem is that the increase's calculation always results in zero. I can't understand why it's happening. I also tried to print the 'perc' variable after receiving its input, but strangely it didn't work.
Some more code:
The definition of struct reg:
#include <stdio.h>
#include <conio.h>
#define SIZE 100
struct reg{
int cod;
char desc[30], type;
float price;
};
At the main function, the only usefull thing for this function is the call of the function itself, and, sure, the declaration of the struct and the count variable(whose value comes from another function according to the number of products).
The type is defined in another function in which you can add products. it's a litteral value like P (for pants), T (for T-shirt) etc.
I am currently trying to make a small game in the c programing language for a portfolio. I am new to c so I don't know all of the ticks. Currently, I am trying to assign values to enum's though I don't know if that is correct.
// C program for generating a
// random number in a given range.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Test.h"
enum mods{
Cha, Str, Dex, Con, Int, Wis // <-this line is the only line that is my code (of this document I have more that will reference this document) the rest I learned from others
};
// Generates and prints 'count' random
// numbers in range [lower, upper].
void printRandoms(int lower, int upper,
int count)
{
int i;
for (i = 0; i < count; i++) {
int num = (rand() %
(upper - lower + 1)) + lower;
printf("%d ", num);
}
}
// Driver code
int main(enum mods Str)
{
int lower = 6, upper = 18, count = 1;
// Use current time as
// seed for random generator
srand(time(0));
printRandoms(lower, upper, count);
printf("My enum Value : %d\n", (int)Str);
return 0;
*edit Sorry for the confusion. I want to be able to reference this product of this line of code over and over again in the main sheet/program. I want it to be a random start so it isn't the same game every time. How do I do that? (for an example of the end product:
if (Str >= 10)
printf("pass skill check to lift the log\n");
else
printf("you drop the log on your foot and take 1d4 damage\n");
enum (health -1d4[will make actual code for this but not yet])
what I need answered
how to make each of the enum mods = a random number at the start of the program to be referenced in the main program
)
If I understood you correctly, you want the mod values to be randomly generated.
Use the enum values as array indices into an array big enough to hold all your mod attributes. Like this, for example:
enum mods = { Cha, Str, Dex, Con, Int, Wis, Mod_Max };
int mod_values[Mod_Max];
Keeping Mod_Max (or whatever you'd like to call it) as the last element of the enum, this will give you simple way to refer to the size of the array. Populating the array with values:
for (int i = 0; i < Mod_Max; i++) {
mod_values[i] = ...;
}
And getting a value of a given "mod" would simply be (for example Str):
mod_values[Str];
EDIT: This way, lets you further modify the mod values down the line, rather than having them as constants
I believe you're asking how to have values for each element in your enum. Well all you have to do is simply assign said value-
enum mods { foo = 77, bar = 42, baz = 3 };
Then you can access said values like so-
enum mods mod_enum = foo;
printf("%d", mod_enum);
The above will print 77
You can also directly use the value of one of the elements from said enum
printf("%d\n", bar);
The above prints 42
Read more about enums
so C-programming noob here. I'm working on some practice questions, and I can't seem to figure out where I'm making a mistake on this one.
I'm pretty sure there is an error in how the pointers are being grabbed by the main function, but I've tried everything I could think of/read up on and have no idea how to resolve my problem.
Some more information about the question - the change calculation has to be a function, and I made up a program to get input from the user to then go through the function and spit out the smallest number of bills/coins used. No small change (quarters,dimes,nickels, pennies), so only int number are required.
#include <stdio.h>
#include <math.h>
int main(void)
{
/* local variable definition of enter amount*/
int dollars, *twenties, *tens, *fives, *toonies, *loonies;
printf("enter amount: ");
scanf("%d", &dollars);
printf("\nChange for $%d is:\n", dollars);
/* Calling pay_amount function to get smallest bills*/
printf("$20s: %d\n", &twenties);
printf("$10s: %d\n", &tens);
printf("$5s: %d\n", &fives);
printf("$2s: %d\n", &toonies);
printf("$1s: %d\n", &loonies);
return;
}
/*Function pay_amount declaration */
void pay_amount(int dollars, int *twenties, int *tens, int *fives, int *toonies, int *loonies)
{
while (dollars>=0);
*twenties = (dollars/20);
*tens = ((dollars%20)/10);
*fives = (((dollars%20)%10)/5);
*toonies = ((((dollars%20)%10)%5)/2);
*loonies = (((((dollars%20)%10)%5)%2));
}
unwanted result example:
enter amount: 120
Change for $120 is:
$20s: -4196336
$10s: -4196340
$5s: -4196344
$2s: -4196348
$1s: -4196352
There are several issues with your program. Here are a few of them.
First, you don't want your actual variables to be pointers, but simple ints for you to point to:
int dollars, twenties, tens, fives, toonies, loonies;
Second, you need to pass the actual variable values to printf, not their addresses:
printf("$20s: %d\n", twenties);
printf("$10s: %d\n", tens);
printf("$5s: %d\n", fives);
printf("$2s: %d\n", toonies);
printf("$1s: %d\n", loonies);
Third, you don't actually call your pay_amount function.
Fourth, if you were to call it, it would loop indefinitely due to this completely extraneous loop that you should just remove:
while (dollars>=0);
Fifth; while this isn't actually a bug (it won't stop your program from working in any way), the additional reminder operations in pay_amount are redundant:
*twenties = (dollars/20);
*tens = ((dollars%20)/10);
*fives = ((dollars%10)/5);
*toonies = ((dollars%5)/2);
*loonies = ((dollars%2));
Sixth, as a note on terminology, this has nothing to do with "function pointers", which signify pointers that point to functions, rather than pointers that are passed to functions.
you need change:
/* local variable definition of enter amount*/
int dollars, *twenties, *tens, *fives, *toonies, *loonies;
to
/* local variable definition of enter amount*/
int dollars, twenties, tens, fives, toonies, loonies;
function pay_amount() like this:
pay_amount(int *dollars,int *twenties,int *tens,int *fives,int *toonies,int *loonies)
call function like this: pay_amount(&dollars, &twenties, etc);
and inside the pay_amount() like this:
while (*dollars>=0);
*dollars/20;
*tens = ((*dollars%20)/10);
So i thought i fixed this yesterday when you guys answered my question, but today i realized that i forgot that i disabled the function named bubbleSort(), once i enabled that function the addRandomNumbers() function directly below main started generating the same number as the random number instead of different numbers again, even though i seeded the generator once at program start. It only generates different random numbers if i disable the bubbleSort() function which is weird because thats an entirely different function.
But i kind of need the bubble sort function so that the binarySearch() function im going to make will work
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define clear system("cls")
#define pause system("pause")
#define SIZE 5000
#define LB 1 //this is the lower bound
#define UB 500 //this is the upper bound
//Lets Prototype
void addRandomNumbers(int n[]);
void binarySearch(int n[],int c[]);
void bubbleSort(int n[]);
void displayRandomNumbers(int n[],int c[]);
int main(){
int numbers[SIZE]={0}, counter[SIZE]={0};
srand((unsigned)time(NULL));
addRandomNumbers(numbers);
bubbleSort(numbers);
binarySearch(numbers,counter);
displayRandomNumbers(numbers,counter);
}//end main
void addRandomNumbers(int n[]){
int i;
for (i=0; i < SIZE; i++){
n[i] = LB + rand() % (UB - LB + 1 );
}
}//end addRandomNumbers
void bubbleSort(int n[]){
int i,temp=0;
for(i=0;i<SIZE-1;i++){
temp=n[i];
n[0]=n[1];
n[i+1]=temp;
}//end for loop
}//end bubble sort
void binarySearch(int n[],int c[]){
int i,k=0,l,u,mid;
for(i=0;i<SIZE;i++){
l=0,u=SIZE-1;
while(l<=u){
mid=(l+u)/2;
if(n[i]==n[mid]){
k++;
break;
}
else if(n[i]<n[mid]){
u=mid-1;
}
else
l=mid+1;
}//end while loop
c[i]=k;
}//end for loop
}
void displayRandomNumbers(int n[], int c[]){
int i;
char flag;
for(i=0;i<UB;i++)
if(c[i]<100)
printf("The number %i appears %i times\n",n[i],c[i]);
pause;
}//end displayRandomNumbers
I think you are seeing the same numbers as displayed output probabilistically.
If I can summarize your program, you:
fill a 5000-length array with numbers between LB (1) and UB (500) (addRandomNumbers function)
sort the array (bubbleSort function)
print the FIRST element (displayRandomNumbers function).
Let's assume your sort function works. The first element of the sorted array will be 1 if that value was sampled for any of the 5000 numbers. It could be 2 if there were no values of 1 selected, could also be 3, etc.
What is the probability that you would observe a 2 or greater number as the first element of the array? It is the probability that ZERO values of 1 were sampled. Assuming uniform probability (which your sampling method does not provide):
p(zero observations of 1) = (499 / 500) ^ (5000) = 0.00005
In other words, it is very likely that your unsorted array will contain a value of 1 somewhere. When you sort it, that value will become the first element of the array.
It's your so-called bubbleSort that's actually not at all an implementation of bubble sort that fills your array with the same number, in a convoluted way. (How could it possibly be a sort function if it doesn't ever compare values of the array?)
Why don't you use the C standard library qsort function if you don't know how to properly implement a sort algorithm?
I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!