How to work with a variable number of variables in C? - c

So I was pondering about this problem in C using only stdio.h -
I have to write a program that reads an integer p and then reads p integers. Now I have to use these p integers and perform another operation on them to get a final answer, which my main program will return.
The problem is I don't know how to perform an operation on a variable number of integers. I tried using pointers but they don't seem to work.
Can anyone help please?
#include <stdio.h>
int main(){
int i, p, n;
scanf ("%d", &p);
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++){
int a=*k;
if (a==0)
i=0;
else i=1;
}
return i;
}
What I want to do here is to read a certain integer p, then read p integers a, and if at least one of these as is 0, my answer is 0. Otherwise it's 1.
But the compiler says *k is not defined for the second for loop. What should I do?

I think you can do this with a fixed number of variables. Like
int p, a, ans=1;
scanf("%d", &p); //read number
for(int r=0; r<p; ++r)
{
scanf("%d", &a);
if(a==0)
{
ans=0;
break;
}
}
printf("\nAnswer is: %d", ans);
ans variable holds the answer. First you read the number of ints into p and then read p number of ints using a loop.
During each iteration of the loop, you read into the same variable a. You just need to know if at least a single input is zero.
ans is initially set to 1 and is changed to 0 only if a zero is input. If zero is input, the control exits the loop immediately because of the break statement.
You may want to check the return value of scanf() and other error checking.
Various ways to use an unknown number of variables is mentioned in the comments.
If you can use C99, variable length array are allowed. Like
int p;
scanf("%d", &p);
int arr[p];
If dynamic memory allocation is used, you could use malloc() or calloc() which are in stdlib.h.
See this.
And the pointer k in
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++){
int a=*k;
if (a==0)
i=0;
else i=1;
}
is a local variable of the first loop and is hence visible only to that loop and is invisible to the second loop. k's scope is limited to the first loop. See this.
If you want a variable to be visible in both the loops, declare it outside both.

First things first, I'll help you understand the compiler error you talked about:
k is not defined for the second for loop
// some code
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a; // Definition of k is here, and is restricted to this block,
}
for (n=0; n<p; n++){
int a=*k; // Its undefined here
if (a==0)
i=0;
else i=1;
}
// some code
Explanation: Read the comment in the code. What I meant by block is the code between the upper '{' and lower '}'. Beyond these, anywhere in code, k is undefined. Hence in second loop, the k is undefined.
You should change your main() function to:
int main()
{
int i, p, n, k = 0;
scanf ("%d", &p);
for (n=0; n<p; n++) {
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++) {
int a=*k;
if (a==0)
i=0;
else
i=1;
}
return i;
}
Now to address your next issue, I guess you might want to study variadic functions in C. I may be wrong in understanding your problem statement, but my take on it is that you are willing to pass multiple arguments to a function. For example,
At some time, you want to call function as:
function(Count_args, 1, 2, 3, 4, 5);
and sometimes as:
function(Count_args, 10);
If I am right, you might want to take a look at this example on the same reference I cited above. For making your life easier, I am adding the same code here:
#include <stdarg.h>
#include <stdio.h>
int
add_em_up (int count,...)
{
va_list ap;
int i, sum;
va_start (ap, count); /* Initialize the argument list. */
sum = 0;
for (i = 0; i < count; i++)
sum += va_arg (ap, int); /* Get the next argument value. */
va_end (ap); /* Clean up. */
return sum;
}
int
main (void)
{
/* This call prints 16. */
printf ("%d\n", add_em_up (3, 5, 5, 6));
/* This call prints 55. */
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
return 0;
}
If you are willing to know that latest standard says about having variable arguments to a function, refer C11, section 7.16 Variable arguments , it does help!

Related

Outputting result of one-dimensional array with calculation in C language?

I am a new person on stackoverflow. I have stuck in a problem when I try to make a program with C language that will print out a maximum element in an one-dimensional array by using functions. I decided print out my element in in many ways. I have try to put "printf" in the "checkmax" fuction, in "main" function and make a function
"printmax" just for print my elements but none of these ways seem like work well.I need some helps.
int checkmax(int a[], int n)
{
int max=a[0];
for(i=0;i<n;i++);
{
if(a[i]>max) max=a[i];
}
return max;
//printf("max = %d", max);
}
/*void printmax()
{
if(checkmax(a,n)==max) printf("max = %d", max)
}*/
int main()
{
int n;
printf("Enter number of elements => ");
scanf("%d",&n);
int *a=(int*)calloc(n,sizeof(int));
inputarray(a,n);
checkmax(a,n);
//printf("max = %d", max);
getchar(); getchar();
}
You have i undeclared in the for loop.
Also this for(i=0;i<n;i++); means that you have an empty for loop because of the semicolon at the end. If you fix these you should be fine.
e.g.
for(int i=0;i<n;i++) {
if(a[i]>max) max=a[i];
}
There are a few errors we should address.
First, you are trying to use local variables as global ones. E.g. trying to use max in printmax() when it was defined locally in checkmax().
Second, your for loop does nothing due to the semicolon at the end. Also make sure to do int i = 0 instead of i = 0, since i was not declared before entering the loop.
Third, if you are getting errors from calling printf(), you should make sure that you included stdio.h at the top of your file: #include <stdio.h>
(the printf() in checkmax() also needs to be before return max;)
Solution:
Remove the declaration of max, a, and n in their functions, and instead declare them at the top of your file,
#include <stdio.h>
int max = 0, n = 0;
int a[] = {0};
...
fix the for loop,
for(int i = 0; i < n; i++){
...
}
and remove printmax(). The function is useless, since you print max in checkmax().

Trouble with horizontal frequency histogram

Am having many problems with coding C. Apologies for any bad mistakes. Im trying to do simple horizontal histogram for frequency of integers in array. No matter what it prints out incorrect and makes infinite loop. I believe the problem lies in printHistogram function. Any tips?
Here is code:
#include <stdio.h>
//Prints histogram to screen using horizontal bar chart
void printHistogram ( int *hist, int n );
int main ( void )
{
int i, n;
printf ("How many values for array? ");
scanf ("%d", &n);
int list[n];
for (i=0; i < n; i++) {
printf ("Enter value: ");
scanf ("%d", &list[i]);
}
// Process data to compute histogram
int hist[10];
// Print histogram
printHistogram ( hist, 10);
return 0;
}
void printHistogram ( int *list, int n )
{
int i, j;
for (i=0; i < n; i++) {
printf ("[%d] ", i);
for (j = 0; j < list[i]; j++)
printf ("*");
printf ("\n");
}
}
The problem is in
for (j = 0; j < list[i]; j++)
when, you're trying to use list[i], but based on the argument passed, the value is indeterminate. So, in this case, this invokes undefined behavior and the loop goes haywire.
To elaborate, you have defined int hist[10]; as a local variable and did not initialize it, so all the members contain indeterminate value. You then, go ahead and pass the array to printHistogram(), inside which, you receive it via list and then, dereference that and expect to get some valid value magically, which is not possible.
OTOH, you are scanning values in list inside the main() and not using it. You need to make some corrections so as to make use of the scanned value later, which seems to be the actual target.

Scanf in to array

This a dot_product function of 2 vectors of the same length.
I don't understand how to build the array because how the machine will know which input goes to which input (for example i want a={1,2,3} but the input of 123 will come a[0]= 123)...
How do I make end of array[index] input and how do I make end of the whole array.
#include <stdio.h>
#include <stdlib.h>
#define MAXINPUT 100
int dot_product(int v[], int u[], int n)
{
int result = 0;
int i;
for (i=0; i < n; i++)
result += v[i]*u[i];
return result;
}
int main(){
int v1[MAXINPUT];
int v2[MAXINPUT];
int count = 0
int i,print;
printf(" first vector:");
for(i=0;i<MAXINPUT;i++){
scanf("%d", &v1[i]);
count +=1;
}
printf(" second vector:");
for(i=0;i<MAXINPUT;i++)
scanf("%d", &v2[i]);
print = dot_product(v1, v2, count);
printf("v1*v2:%d",print);
return 0;
}
The first problem I observe here is with
count +=1;
where count is an uninitialized automatic local variable, which makes it's initial value indeterminate. Attempt to use that value invokes undefined behavior.
You should be initializing count to 0.
That said, here, you're depending on the user to input the second array with exact same dimension of that of the first one. In case that does not happen, your program will blow up, as you did not initialize the arrays, again.

My program crashes, I don't understand why it does not even reach the first printf

My program is supposed to order a list of numbers inputed by the user, but it crashes even before reaching the first printf. My compiler makes 2 warnings, but I don't see the issue. I haven't studied pointers yet, so I didn't want to use them. Here are the messages:
In function `selection_sort':
[Warning] passing arg 2 of `selection_sort' makes pointer from integer without a cast
In function `main':
[Warning] passing arg 2 of `selection_sort' makes pointer from integer without a cast
.
#include<stdio.h>
int selection_sort(int n, int v[n])
{
int high = v[0];
int i;
for(i = 0; i < n; i++)
high = high < v[i]? v[i] : high;
if(n - 1 == 0)
return;
v[n - 1] = high;
n -= 1;
selection_sort(n, v[n]);
}
int main(void)
{
int n, i;
int v[n];
printf("Enter how many numbers are to be sorted: ");
scanf("%d", &n);
printf("Enter numbers to be sorted: ");
for(i = 0; i < n; i++)
scanf("%d", &v[i]);
selection_sort(n, v[n]);
printf("In crescent order: ");
for(i = 0; i < n; i++)
printf("%d ", v[i]);
getch();
return 0;
}
Your program is using a variable length array, a feature that was added in C99.
However, you declare its size based on an uninitialized variable. What did you believe would happen there?
In C, variables declared inside functions are NOT set to 0. They are not set to anything. They pick up whatever value was left on the stack or in the register that they are assigned.
I believe that your program is crashing because n in int v[n] is a ridiculously big number and v is trying to use too much memory.
You can probably fix this by moving your array declaration below the scanf that reads in n.
You need to pass v, not v[n] to the function selection_sort. v is the array, v[n] is actually an out of bounds element of v.
the line should be selection_sort(n, v);

scanf infinite loop

This program takes the first number in a file and indicates how many numbers are going to be after it, then does various other things with the numbers that follow.
It seems like scanf is causing an infinite loop when trying to read from the file. WHen I run the program not even the check at 1 works
Here is the code:
#include <stdio.h>
int main(void) {
int N, a, n;
int x=0;
int t=0;
printf("1"); //Check
scanf("%d", &N);
printf("2"); //Check
int nums[N];
int i;
printf("%d", &N); //Check
for (i=0; i<N; i++)
{
scanf("%d", &nums[i]);
t+=nums[i];
if (nums[i] > x) x=nums[i];
if (i=0 || nums[i] < n) n = nums[i];
}
a = t/N;
printf("Number Processed: \t%d\n", &N);
printf("Maximum: \t%d\n", &x);
printf("Minimum: \t%d\n", &n);
printf("Total: \t%d\n", &t);
printf("Average: \t%d\n", &a);
}
The way i run the program is
gcc -lab16
./a.out <in1
where in1 is text and has the numbers
7
6
-30
90
3903
-934
443
445
Thanks for your time.
if (i=0 || nums[i] < n) n = nums[i];
you are assigning i = 0, so the loop never realy advances! You probably wanted i == 0. This is causing the infinite loop.
Other issue: int nums[N]; - if you want an array of dynamic [determined in run-time] size, you will probably need to malloc() it.
Update: note that int nums[N] is valid in C99, so if your assigment is assuming C99 you should not worry about this issue. Otherwise - malloc() will be needed:
int* nums = (int*) malloc(sizeof(int) * N)
And don't forget to free(nums) before the program ends, or you will get memory leak.
if (i=0 || nums[i] < n) n = nums[i];
This is the culprit. You are making an assignment i=0 when you should do a comparison : i==0
Your loop goes to infinity because everytime you are i to 0.
Moreover, the code you gave us, gave me an error, because you were creating new variables during runtime.
#include <stdio.h>
#include "stdlib.h"
int main(void) {
int N, a, n;
int x=0;
int t=0;
int i;
int *nums;
printf("1"); //Check
scanf("%d", &N);
printf("2"); //Check
nums = malloc(N*sizeof(int));
....
There are numerous problems with this code.
You mistook assignment for comparison:
i=0
sets i to zero. You probably meant
i==0
which checks whether i is equal to zero.
You should check the value returned by scanf(). When data read by scanf() doesn't fit the format you specified it leaves the data in the buffer and the next call to scanf() sees the same data again.
The reason that the first printf() doesn't print anything is most likely that you are not printing any newline. Note that on some output devices like terminals output is line-buffered.
You are passing a pointer to a variable to printf(), but your format specifies %d. You probably meant the variable itself, not a pointer to it.
Also, if you need an array of length dependent on a value known only at runtime, you need to allocate it on the heap, e.g. using malloc().

Resources