C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-21-2008, 03:02 PM   #16
Registered User
 
Join Date: Jul 2008
Posts: 8
valaris : thanks, but your suggestions didn't work for me.

i don't know how to make this damn thing run using a pointer to a pointer, so i'm just gonna stick with returning the pointer at the end of the function (this now makes alot of sense to me).
I've also updated a few coding faux pas (except 2):

some serious
Code:
integers = malloc(*num1 * sizeof(int));  to  integers = malloc((*num1 + 1) * sizeof(int));
Code:
int   *integers = 0; // undefined behavior bad
int   num1 = 0;
some not so serious
Code:
main() to int main(void)
Code:
return 0;
Code:
int *allocate_memory(int *integers, int *num1); // not just the prototypes
int average_of(int *integers, int *num1);
int print_average(int *integers, int *num1);
some just plain stupid (in an attempt to understand)
Code:
 integers = ptr;
But.....

1)fflush(stdin) must stay, because the getchar() doesn't work if its not there...see for yourself, it doesn't wait for a character return.
matsp: fflush(stdout) does not make sense to me. It flushes the standard output, after those scanfs i have to flush the standard input to do a getchar().

2)Between copying a value in to a function (int num1) vs copying a pointer to a value in to a function (int *num1). I don't know whether one or the other is more efficient, or if they are equal. I know i'm not changing the value of num1 (except in the allocate_memory function), but do i really need to change all of the other int *num1's to int num1's... ?

heres my code:

Code:
#include <stdio.h>
#include <stdlib.h>


int *allocate_memory(int *integers, int *num1);
int average_of(int *integers, int *num1);
int print_average(int *integers, int *num1);


int *allocate_memory(int *integers, int *num1)
{

            
    printf("How many numbers do you want to average: ");
    scanf("%d", num1);
    
    integers = malloc((*num1 + 1) * sizeof(int));
    
    if(integers == NULL)
      {
         printf("malloc has failed\n");
         exit(1);
      }
    
    return integers;
}


int average_of(int *integers, int *num1)
{
   int    i;

   integers[*num1] = 0;

   for(i = 0; i < *num1; i++)
      {
         printf("#%d Please enter a number: ", i + 1);
         scanf("%d", &integers[i]);
         integers[*num1] += integers[i];
      }
   integers[*num1] /= *num1;
}

int print_average(int *integers, int *num1)
{
   int    i;
   
   printf("The average of ");
   
   for(i = 0; i < *num1; i++)
      printf("%d ", integers[i]);
      
   printf("is : %d\n", integers[*num1]);
}

int main(void)
{
   int   *integers = 0;
   int   num1 = 0;
    
   
  
   integers = allocate_memory(integers, &num1);
   average_of(integers, &num1);
   print_average(integers, &num1);
   
   free(integers);
   
   fflush(stdin);
   getchar();
   
   return 0;
}
Thanks again, to everyone who has posted so far.
polymatrix is offline   Reply With Quote
Old 07-21-2008, 03:18 PM   #17
Deathray Engineer
 
MacGyver's Avatar
 
Join Date: Mar 2007
Posts: 3,211
Quote:
Originally Posted by polymatrix View Post
But.....

1)fflush(stdin) must stay, because the getchar() doesn't work if its not there...see for yourself, it doesn't wait for a character return.
There is no "see for yourself" with undefined behavior. matsp can stick it in his code and it may crash the program, or it may delete the file, or it may start playing minesweeper on his computer. The idea of something being "undefined" means that the C standard allows anything to happen, which means your compiler and system may work the way you intended (ie. discard chars you don't want), but other compilers and systems may do something not-so-nice and unexpected (ie. crash or even mutilate or lose valid input). Either way, no matter what it does, the C standard says it's ok because calling fflush() on an input stream is not defined.
__________________
MacGyver is offline   Reply With Quote
Old 07-21-2008, 03:27 PM   #18
Registered User
 
Join Date: Jul 2008
Posts: 8
Thanks Macgyver. What should i use to flush the standard input?
polymatrix is offline   Reply With Quote
Old 07-21-2008, 03:40 PM   #19
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
And how to solve it is in the FAQ How do I ... (Level 2):
http://faq.cprogramming.com/cgi-bin/...&id=1043284392

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 07-21-2008, 04:08 PM   #20
Rampaging 35 Stone Welsh
 
abachler's Avatar
 
Join Date: Apr 2007
Posts: 2,926
Quote:
Originally Posted by tabstop View Post
You can change what is pointed to by a function parameter, but you can never change the thing itself. So in your example, integers was a pointer to some integers -- those integers could be changed, because they were pointed to, but the value of integers itself could not be changed -- integers could not be set to point to a new bunch of integers.

Edit: That's a really confusing name, so maybe the typeface will help.
of course you could always pass a pointer to the pointer as so -

Code:
void foo(int** integers , int num){
   *integers = (int*)malloc(num * sizeof(int));
   
   return;
   }
 
void main(void){ // love you sweety
   
   int* integers;
   int num = 5;
 
   printf("integers* = %d\n" , integers);
 
   foo(&integers , num);
 
   // integers now points to an array of integers
   printf("integers* = %d\n" , integers);
 
   return;
   }
__________________
He is free, you say. Ah! That is his misfortune… These men… [have] the most terrible, the most imperious of masters, that is, need. … They must therefore find someone to hire them, or die of hunger. Is that to be free? - Simon Linguet
abachler is offline   Reply With Quote
Old 07-22-2008, 12:55 AM   #21
Registered User
 
Join Date: Jul 2008
Posts: 8
This is weird to me...but its pretty cool. I was not familiar with the ** operator.
So, ** essentially means: a pointer to a pointer? Valaris, your previous post makes more sense to me now. You gave me the answer, thank you.

Abachler: thanks... your code helped me see what i was doing wrong. I wasn't calling allocate_memory(&integers, &num1)... i was calling ( integers, &num1). I thought &integers would be redundant syntax (the address of the address of integers), its not. I'm kinda sorta starting to get it. **integers is a pointer to *integers address, so in the function the address of *integers is alterable...right?

Macgyver and matsp: I only hope, one day i'll understand the language like you too do. From what i can gather the new version of fflush(stdin) is:

Code:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
1)This creates an int variable called ch
2)executes an infinite do nothing while loop if the condition ((ch = getchar()) != '\n' && ch != EOF); is met.
3)((ch = getchar()) != '\n' && ch != EOF) means ch equals the return value of getchar . if this is not equal to a newline character and ch is not equal to EOF do nothing and evaluate the condition again.

Is this right? because i don't get it.
It works though.... just replaced fflush(stdin) with
while ((ch = getchar()) != '\n' && ch != EOF); and it does the same thing.
for me though, its more undefined than fflush(stdin) is to the compiler. I would really appreciate an explanation .

here's my new code:

Code:
#include <stdio.h>
#include <stdlib.h>


int allocate_memory(int **integers, int *num1);
int average_of(int *integers, int *num1);
int print_average(int *integers, int *num1);


int allocate_memory(int **integers, int *num1)
{

            
    printf("How many numbers do you want to average: ");
    scanf("%d", num1);
    
    *integers = malloc((*num1 + 1) * sizeof(int));
    
    if(integers == NULL)
      {
         printf("malloc has failed\n");
         exit(1);
      }
    
}


int average_of(int *integers, int *num1)
{
   int    i;

   integers[*num1] = 0;

   for(i = 0; i < *num1; i++)
      {
         printf("#%d Please enter a number: ", i + 1);
         scanf("%d", &integers[i]);
         integers[*num1] += integers[i];
      }
   integers[*num1] /= *num1;
}

int print_average(int *integers, int *num1)
{
   int    i;
   
   printf("The average of ");
   
   for(i = 0; i < *num1; i++)
      printf("%d ", integers[i]);
      
   printf("is : %d\n", integers[*num1]);
}

int main(void)
{
   int   *integers = 0;
   int   num1 = 0;
   int   ch; 
   
  
   allocate_memory(&integers, &num1);
   average_of(integers, &num1);
   print_average(integers, &num1);
   
   free(integers);
   
   while ((ch = getchar()) != '\n' && ch != EOF);
   getchar();
   
   return 0;
}
Is this better?
Is this standard C?
Thanks everybody.
polymatrix is offline   Reply With Quote
Old 07-22-2008, 02:16 AM   #22
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Definitely better.
Is it standard - well, "gcc -Wall -ansi -pedantic -O2" gives no errors/warnings indicating non-standardness, so that's a good sign. You do have some warnings, but that's commented on below.

Your understanding of the "remove input" (or fflush(stdin)) is correct - it reads one character at a time until it reaches either newline or end of file.

In allocate_memory(): Whilst this line is syntactically correct, it is not what you want:
Code:
    if(integers == NULL)
You want to check if the value returned from malloc is NULL, not if the pointer you passed in from main is NULL, so check *integers [although, if you want to be really pedantic, yes, you should check that TOO - but that should be done BEFORE the call to malloc, and if we are that pedantic, you should also check if num1 is NULL].

In average_of(): You do not need to pass num1 as a pointer. Same with print_average().

I personally would not use the last element of the array to store the average, but instead return a value from the average_of function, and pass that value to the print_average() function.

All of your functions have an integer return type, but besides main, all functions have no return statement. You may want to make those functions have a void return type.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.

Last edited by matsp; 07-22-2008 at 02:18 AM.
matsp is offline   Reply With Quote
Reply

Tags
c programming, code examples, pointers, question, standard

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
funcion runs 14 times, then program crashes happyclown C Programming 9 03-03-2009 11:58 PM
prog runs on 64bit - seg faults on 32bit hollie C Programming 13 12-08-2006 01:59 AM
windows installer for psp runs for vs6 iain Tech Board 1 06-27-2004 09:21 AM
What is wrong with this simple program? runs in the background and takes all of cpu Shadow12345 Windows Programming 6 10-24-2002 08:58 AM
Runs fine in IDE but crashes normally! Hunter2 Windows Programming 5 05-07-2002 03:47 PM


All times are GMT -6. The time now is 03:33 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22