Learning c programming - passing array into function - c

May i know why is int count, biggest = -12000;? Why must it be -12000 and I do not understand this statement biggest = -12000
If I put biggest = 10000, it can still compile. Appreciate your advise as I am currently learning c programming. Can you please understand as clearly as possible? Thanks in advance!
#include <stdio.h>
#define MAX 10
int array[MAX], count;
int largest(int x[], int y);
int main()
{
/* Input MAX values from the keyboard. */
for (count = 0; count < MAX; count++)
{
printf("\nEnter an integer value:\n ");
scanf_s("&d", &array[count]);
}
/* Call the function and display the return value. */
printf("\n\nLargest value = %d\n", largest(array, MAX));
return 0;
}
/* Function largest() returns the largest value in an integer array */
int largest(int x[], int y)
{
int count, biggest = -12000;
for (count = 0; count < y; count++)
{
if (x[count] > biggest)
biggest = x[count];
}
getchar();
return biggest;
}

If you want to find the largest number in an array you compare all elements against the currently 'biggest' value. Whenever you find a value that's larger you put it in biggest.
To make sure that you find the proper value you must initialize biggest to a sensible value.
Your code initializes biggest to -12000, and therefore it will fail if all elements in the array have values lower than -12000 (unless you know something about the values in the array, but then that should be mentioned in a comment, to explain the unusual initialization value).
Sure it will compile, but that does not mean it will work correctly.
You could initialize biggest to the lowest integer value possible (INT_MIN),
int largest(int x[], int y)
{
int count, biggest = INT_MIN; // lowest integer value possible
for (count = 0; count < y; count++)
{
but a smart trick is to initialize it to the first value in your array.
int largest(int x[], int y)
{
int count, biggest = x[0]; // first value in your array
for (count = 1; count < y; count++) // starting with 2nd element
{
You can work this all out on a piece of paper with e.g. 3 array values, or step through your debugger and see what values the respective variables get.

Instead of assigning the value in starting to biggest, you can compare two elements of the array and after comparing it store maximum value in biggest and after it swap the numbers if greater it would be good approach.
if you use like:
if(x[count]>x[count+1])
biggest=x[count];
x[count]=x[count+1];
x[count+1]=biggest;
code above line in loop.
What you tried assigned a very high value to biggest. It's not a worthy idea.

Related

How to find the largest integer among an infinite number of integers in C

#include <stdio.h>
int main()
{
int res;
int max;
int i;
int Maximum;
for (i = 0 ; i < res; i++)
{
res = scanf("%d",&max);
if( res != 1 ) return 0;
if(max > Maximum)
{
Maximum = max;
}
}
printf("%d",&Maximum );
return 0;
}
Hi guys, I don't understand why Maximum prints out an obscene high number.
Just want a reason why, not something to hold my hand, for I really want to learn this language, I know Java mostly so what's happening here?
1. No need to pass address of integer variable.Else right now you are passing wrong argument to %d causes undefined behaviour.
printf("%d",&Maximum );
^ remove &
To print value of Maximum-
printf("%d", Maximum);
2. Maximum is unitialized in you program , therefore ,comparing it without initialization is incorrect.
int Maximum; // unintialized variable
Initialize it before using -
int Maximum=INT_MIN; // header <limits.h>
3. This loop of yours is not infinite. It will just iterate for 1 time -
for (i = 0 ; i < res; i++)
{
//your code
}
Instead use an infinite loop -
for(; ;){ // or while(1)
//your code
}
Initialize some value for the variable Maximum.
Maximum=0; // you can assign any value.
Then You have to change this line,
printf("%d",&Maximum );
into
printf("%d",Maximum );
&Maximum will give the address of the integer variable. While getting the input from scanf only we have to give like that.
Initialize Maximum to some value which is lowest for all the possible input values.
e.g. If input is guaranteed to contain only the positive integers then
Maximum = -1;
Or better use Maximum = INT_MIN; as pointed in comments. For that you'll need to include <limits.h> header file in your program.
printf("%d",&Maximum );
This is wrong. This will print the address of Maximum.
Use printf("%d", Maximum);
for (i = 0 ; i < res; i++)
res is not initialized! For an infinite numbers you'll want to make this loop infinite as while(1) or for( ; ; )
Because the program cannot know whether user will input only negative numbers, only positive numbers, or both, initializing "max" (or min) to a random number (such as zero) with the hope that it would "definitely" be maximum / minimum during the course of the execution, is likely to give erroneous results at some point.
The following is a simplistic approach that solely relies on user input, without trying to include any additional header files for absolute min / max values. It assumes the first provided input as "max", and if any subsequent entry surpasses that value, max is reset.
#include <stdio.h>
int main(void) {
int num, max;
int first_input = 1;
while(scanf("%d", &num) != EOF){
if(first_input){
max = num;
first_input = 0;
}
else{
if(max < num){
max = num;
}
}
}
printf("\n Maximum of the scanned numbers is: %d", max);
return 0;
}
The program will continue running until the user terminates the input by hitting Ctrl+D / Ctrl+Z.

Correctly passing an array from a function

I have some code to generate an array of size [user_input] in a function called array_generator, using size of array from scanf in main(), and then filling it with the numbers 0 to user_input (0, 1, 2, 3, if user input is 4). The array fills correctly as printf prints
`The array contains the value 1`
`The array contains the value 2`
`The array contains the value 3`, etc.
However when I pass the array to main and printf the array values I get equal statements filled with garbage numbers. I'm also 90% sure I have been passing the arrays and pointers incorrectly (new to them).
The code is below:
#include <stdio.h>
int *array_generator(int number_songs);
int main(void)
{
int input;
int *p;
int i;
int x;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
p = array_generator(input);
x = *p;
for (i = 0; i < input; i++)
{
printf("The array contains the values %d\n", x);
}
return 0;
}
int *array_generator(int n)
{
int a[n];
int *p;
int i;
for (i = 0; i < n; i++)
{
a[i] = i;
printf("The array contains the values %d\n", i);
}
return p = &a[n];
}
One simple solution is to define an array which is bigger than the largest list of songs reasonably possible. For example, since you print every entry, more than a few hundred are not reasonable. On a modern computer space is abundant. You would have a define for the max size on top of the prog, or later in some header:
#define MAX_SONGLIST_LEN 1000
The array can be global, or it can be static inside the function. Let's make it static because you want the function to return the address.
The change is minimal. Just say
static int a[MAX_SONGLIST_LEN];
You may want to change the loop and check for the max length as well:
for (i = 0; i < input && i < MAX_SONGLIST_LEN; i++)
inside array_generator() and main(). You also may want to inform your users about the maximum, and catch numbers which are too large. (You don't do any error handling of user input anyway -- what happens if the user enters a letter instead of a number? Look into the return value of scanf().)
The static array's life time is the lifetime of the program. It will be initialized to all zeroes by the way. If you want to randomly initialize it look at the rand() function.
You are correct in that you are using pointers wrong. The code below preforms the function that you want...
#include <stdio.h>
void array_generator(int n, int arr[]) {
for (int i = 0; i < n; i++) {
arr[i] = i;//array values
//printf("The array contains the values %d\n", i);
}
}
int main() {
int input;
printf("Enter number of songs wanted in random playlist: ");
scanf("%d", &input);
int array[input];//declare array with length of input
array_generator(input, array);
for(int i=0; i<sizeof(array)/sizeof(array[0]); i++) {//input could also be used at the limit to the for loop
printf("%d", array[i]);
}
printf("\n");
return 0;
}
What you are doing is you are over complicating your code. The first thing you do is you create a function and try to make it return an array. This is not necessary. All you need to do is pass a pointer to the array and all edits to the array will be made on the same scope as the array was declared on.
You also mentioned that you want to find the size of an array. This can be done with array *a of any type and sizeof(a)/sizeof(a[0]). This works by returning the number of bytes used by the array divided by the number of bytes used by the first element in the array.
One more thing that you have that you don't need is x = *p;. when you do this, you are essentially doing this x=*p=array_gen(input);
More information on pointers in C can be found here.

Maximum And Minimum With Pointer

I tried to run this but it keeps give me zero value. What is wrong in this code?
#include<stdio.h>
main(){
int i,min,max,arr[3]={10,20,40};
int *ptr_arr;
ptr_arr=&arr[3];
for(i=0;i<3;i++){
if(max>*ptr_arr)
max=*ptr_arr;
if(min>*ptr_arr)
min=*ptr_arr;
}
printf("The Maximum Number Is %d\n ",max);
printf("The Minimum Number Is %d ",min);
}
ptr_arr=&arr[3]; // points to index which is beyond no. of index of array
As declaration of arr is arr[3]={10,20,40};so it's valid indexes are 0,1 and 2 .So there is no index 3(array indexing starts with 0).
Also min and max what value does they have ? Uninitialized , so how can your code give correct output.
Make the following changes -
int min=arr[0],max=0;
...
ptr_arr=arr; // points to address of array's first element
And in for loop see condition and increment pointer-
if(max>*ptr_arr) // change condition to max<=*ptr_arr
...
ptr_arr++;
See worning example here-https://ideone.com/r3nv8R
The code misses to initialise min and max to meaningful values.
Do
int min = INT_MAX;
int max = -INT_MAX;
to have the macro above available #include <limits.h>.
ptr_arr gets initialised wrongly to point beyond the array.
Do
int * ptr_arr = arr; /* Here the array "decays" to address of its 1st element. */
or
int * ptr_arr = &arr[0]; /* Explicitly use the address of the array 1st element. */
The code misses to increase ptr_arr to successively access all array's element while looping.
Add
++ptr_arr;
as last statement to the loop.
Also read your code closely to find a nasty typo in comparing.
main() should at least read int main(void).
Just few notes on your code:
you should give min and max an initial value(a value from the array), why? because the initial garbage value might be beyond your array values(say 9999 for example) which yields a wrong result, because your array doesn't have such a value.
Also, im not sure why you need ptr_arr ?
Here is a modified version of your code:
#include<stdio.h>
int main(){
int i,min,max,arr[3]={10,20,40};
max = arr[0]; //initialize 'max' to be the first element of the array
min = arr[0]; //initialize 'min' to be the first element of the array
for(i=0;i<3;i++){
if(arr[i] >= max)
max = arr[i];
if(arr[i] <= min)
min = arr[i];
}
printf("The Maximum Number Is %d\n ",max);
printf("The Minimum Number Is %d ",min);
return 0;
}
Notice also in the if statement i added <= and >=.
Tested and working:
#include <stdio.h>
int main(void) {
int i = 0,min ,max,arr[3]={20,40,10};
int *ptr_arr;
ptr_arr=&arr[0];
min = max = arr[0];
for(i=0;i<3;i++){
if(max < ptr_arr[i]) {
max=ptr_arr[i];
}
if(min>ptr_arr[i]){
min=ptr_arr[i];
}
}
printf("The Maximum Number Is %d\n ",max);
printf("The Minimum Number Is %d ",min);
}
OUTPUT:
The Maximum Number Is 40
The Minimum Number Is 10

Why is my variable changing values in recursive call in my C program?

I wrote a program to find the largest number in an array. The problem is that every time the find_largest function is called recursively, the largest variable seems to be filled with garbage from somewhere else in memory. I've stepped through it with a debugger and it seems to be working fine until the recursive call. The pointers for the array and the update to largest, if applicable, show expected values.
/*This program will find the largest integer in an array. It was written to practice
using recursion.*/
#include <stdio.h>
void find_largest(int *a, int n);
int main() {
int a[] = {10, 27, 101, -8, 16, 93};
int n = 6, i = 0;
printf("Current array: ");
while(i < n) {//print array
printf("%d ", a[i]);
i++;
}
find_largest(a, n);
return 0;
}//end main
//This function will start at the last element, and then step through the array
//in reverse order using pointers.
void find_largest(int *a, int n) { //formulate the size-n problem.
int largest = 0;
if(n == 0) { //find the stopping condition and the corresponding return
printf("\nThe largest number is: %d \n", largest);
}
else { //formulate the size-m problem.
n--; //decrement so that the proper number is added to pointer reference
if(largest <= *(a + n)) //check if element is larger
largest = *(a + n); //if larger, assign to largest
find_largest(a, n); //recursive call
}
}
The program returns zero as the largest integer. Any ideas?
largest isn't shared by all of your recursive calls, each gets its own copy. That means in the base case, you execute this code:
int largest = 0;
if (n == 0) {
printf("\nThe largest number is: %d \n", largest);
}
Where largest will always be 0.
You can make largest static and it will work, though it's a bit of a strange way to go about it. I'd prefer to do something like this:
int find_largest(int *a, int n)
{
int subproblem;
// base case - single element array, just return that element
if (n == 1)
{
return *a;
}
// recursion - find the largest number in the rest of the array (increase
// array pointer by one, decrease length by one)
subproblem = find_largest(a + 1, n - 1);
// if the current element is greater than the result of the subproblem,
// the current element is the largest we've found so far - return it.
if (*a > subproblem)
return *a;
// otherwise, return the result of the subproblem
else
return subproblem;
}
largest is initialized to 0 in each separate function call, here's a quick fix:
int find_largest(int *a, int n) { //formulate the size-n problem.
static int largest = 0;
if(!n) { //find the stopping condition and the corresponding return
int answer = largest;
largest = 0;
return answer;
}
else { //formulate the size-m problem.
n--; //decrement so that the proper number is added to pointer reference
if(largest <= *(a + n)) //check if element is larger
largest = *(a + n); //if larger, assign to largest
find_largest(a, n); //recursive call
}
}
The static attribute tells the compiler that you only want to initialize the variable once, and afterwards it should retain it's data. This will fix your problem because after each recursive call, largest wont be reset to zero. Instead, it will contain the value of the last call (in this case, the calling function).
At the end of the function, you should reset largest to 0 so that in the next call, it doesn't still contain the value of the call previous. This is also why a temporary variable is made - so that it can return its value before it's set to 0.
Each time you call find_largest(), you're creating a local variable int largest and assigning it the value of zero. So when n finally reaches zero, it doesn't really care what the past 5 recursive calls have done, it simply returns the zero to which you just set largest. Either make largest global, or pass it as a parameter to the function (probably better practice).
make the int largest=0; into static int largest=0; it may help.By adding static the variable largest will be initialized only once throughout your recursion.

Pascal's triangle in C with combinations

#include <stdio.h>
long factorial(int num)
{
int counter;
int fact = 1;
for (counter = num; counter > 0; counter--) fact *= counter;
return fact;
}
float combinations(int n, int k)
{
int numerator = factorial(n);
int denominator = factorial(k) * factorial(n-k);
float fraction = numerator/denominator;
return fraction;
}
int main()
{
printf("How many rows of Pascal\'s triangle should I print?\t");
int rows = GetInteger();
int counter;
int counter2;
for (counter = 1; counter <= rows; counter++)
{
int y = rows-counter;
for (; y > 0; y--) printf(" ");
for (counter2 = 0; counter2 <= counter; counter2++)
printf("%6.0lu", (long) combinations(counter, counter2));
printf("\n");
}
}
Every time I go past twelve rows, the numbers start to decrease. What am i doing wrong?
And, GetInteger() is just a scanf() with a few touch ups. I am 100% sure it works perfectly.
After 12th row factorial and so pascal triangle elements become too large so int type cannot hold them - so you get overflow (most probably values you get are wrapped around maximum int value).
P.S. why do you use 3 different types in your code (long, int, float)? As k!*(n-k)! always divides n! you do not need float value (you use integer division and cast result to long anyway). Just use the biggest integer type you can, or some custom BigInt type that can hold integer numbers of arbitrary length - so you can show correct values for large row numbers.
Don't start from factorials. Start from the following facts about Pascal's triangle:
the nth row of the triangle has n elements (if we start counting from 1)
the first and last elements of each row are 1
each element aside from the first and last one is the sum of the two elements diagonally above it (if the triangle is written in a symmetric way)
You will of course be limited by the size of the data type you are holding results in, but not any sooner than necessary (by intermediate results such as factorials).
INT_MAX is usually 2,147,483,647
12! is 479,001,600
13! is 6,227,020,800 but your function factorial(13) returns 1,932,053,504 (= 6,227,020,800 - 4,294,967,296)

Resources