I'm trying to write code for the gas station problem, where you have a fixed number of cities(linear) and you want to get from one end to the other with as few stops as possible, stopping wherever necessary to refill your gas tank. This is my main function; the function for calculation I've left out for now.
I keep segfaulting saying unable to access tank and arr during the call to solver(the function I'm using to solve).
int main(void)
{
int tank;
int cities;
int ans;
scanf("%d %d",&cities, &tank);
int *arr;
arr=(int *)calloc(cities,sizeof(int));
int *arr2;
arr2=(int *)calloc(cities,sizeof(int));
int i;
for(i=0;i<cities;++i)
scanf("%d",&arr[i]);
arr2[i]=0;
for(i=1;i<cities;++i)
arr2[i]=arr[i]-arr[i-1];
for(i=0;i<cities;++i)
printf(" %d ",arr2[i]);
ans=solver(tank, arr2,cities);
printf("\n ans is %d",ans);
return 0;
}
Can I get some pointers here(terrible pun)?
I'm using the input as:
6 3
0
1
3
4
7
10
Arr holds [0,1,3,4,7,10]
Arr2 holds the differences.
Your loop statement is the problem because of missing encolsing {}:
for(i=0;i<cities;++i) // loop
scanf("%d",&arr[i]); // but there is no enclosing braces. so this is the only statement that loops
arr2[i]=0; //<<<<<< this is executed when loop is finished, i.e i==cities
In other words, you assign arr2[cities], which is out of bouds as it's indexed from 0 to cities-1. This causes the segfault.
Looking at the rest of the code, I guess you inteded to to:
...
for(i=0;i<cities;++i) { // loop, but for the block
scanf("%d",&arr[i]);
arr2[i]=0;
}
...
Related
Im trying to make a program which says how many times a specific digit appears on a 100 numbers sequence.
Meanwhile I got this error and I can´t understand what is the solution to this. I´d appreciate if you could get me some tip or the solution.
#include <stdio.h>
int main() {
int i, m, digit, val[99], count=0;
printf("Enter a number:");
scanf("%d", &val[0]);
while (val[0] < 0) {
printf("Enter a number:");
scanf("%d", &val[0]);
}
for (i=1;i<101;i++) {
val[i]=val[0]++;
printf("%d\n", val[i]);
}
printf("Enter a digit:");
scanf("%d", &m);
while (m<0||m>9) {
printf("Enter a digit:");
scanf("%d", &m);
}
do {
digit=val[i]%10;
val[i]=val[i]/10;
if (digit==m) {
count++;
}
}while (val[i]>0);
printf("The digit %d is printed %d times in this sequence.", m, count);
}
In the for loop you step outside of the array val of which the last index is 98. Instead of hard-coding the length of the array in several places it is more convenient to use a length macro, like this:
#define LEN(anArray) (sizeof (anArray) / sizeof (anArray)[0])
...
for (i = 1; i < LEN(val); i++) {
...
Also, in the do-while loop the index i is outside of the array bounds of val. You also need to check the return value of scanf to make sure the input is valid. The last printf statement also needs a trailing newline.
Edit: Note that LEN only handles "real" arrays; arrays passed to functions are received as pointers.
You allocated only int /* ... */ val[99] (only val[0] to val[98] are available) and accessed upto val[100] because the loop condition is i<101.
This will lead to dangerous out-of-range write (undefined behaior).
Allocate enough elements like int /* ... */ val[101] or fix the loop condition not to cause out-of-range access.
Also you didn't set value of i after the for (i=1;i<101;i++) loop, so value of uninitialized element will be used in the do ... while loop. Values of uninitialized elements of non-static local variables are indeterminate and using the value invokes undefned behavior.
Set i to proper value before the loop or change the indice i to proper thing.
#include <stdio.h>
main()
{
int a[2][5], i,j; //2d array declaration
for(i=0;i<=1;i++) //first loop for 1st dimension
{
for(j=0;j<=4;j++) //nested loop for 2nd dimention
{
printf("Value for a[%d][%d] is : ", i,j);
scanf("%d", &a[i][j]); //asks for value
}
}
}
In this program, when the loop is executing, in the first run, i=0, and inside that j=0,1,2,3,4.
When this is done and it comes to the 2nd dimension where i=1, why does it run the nested loop again when the condition is already false (j<=4)?
Where are all these constant values saved? Does it restart the value of j when the nested loop is run again?
A for loop has three components (expressions) in the form for (A;B;C):
A - Pre-Iteration, run once at the start
B - Loop Condition, tested before each iteration, including the first
C - Post-Iteration, executed after each iteration
You're asking to initialize j=0 each time the loop starts, then testing j <= 4 which will be true. When the loop repeats it does j++, then tests again.
It's worth noting that these are all optional and for (;;) is valid, but is an infinite loop unless you break it.
With minor improvements:
int main(void) //added int and void to main
{
int a[2][5], i,j; //2d array declaration
for(i=0;i<2;i++) //first loop for 1st dimension
{
for(j=0;j<5;j++) //nested loop for 2nd dimention
{
scanf("%d", &a[i][j]); //asks for value [note, before printf]
printf("Value for a[%d][%d] is %d\n: ", i,j, a[i][j]);
}
}
return 0;//int main(void) requires a return statement
//Note also, 'main()' is really not a proper signature for
//the main function
}
This code intends to assign values to each member of the 2D array by using prompted input values using scanf, but because of some syntax and logic errors, the original would not work as intended. To help, the order of the two lines in the nested for loops has been switched to prevent the array from being accessed before being initialized.
The nested for loop indexes have been modified in this version to use the same values for limit, as those used to size the array in its declaration:
int a[2][5];
for(i=0;i<2;i++)
for(i=0;j<5;i++)
scanf() is the method used for user input. Each call prompts for a value, which is placed into the corresponding row-column index indicated by i and j, and written to stdout. Note the actual value in the original code is not printed out, but it is in this slightly modified version.
The value of j is initialized to 0 each time you run the nested loop because you set the initialize expression of the for statement to "j=0"
That expression will be run for each execution of the outer loop
I am a beginner to C language and also computer programming. I have been trying to solve small problems to build up my skills. Recently, I am trying to solve a problem that says to take input that will decide the number of series it will have, and add the first and last number of a series. My code is not working and I have tried for hours. Can anyone help me solve it?
Here is what I have tried so far.
#include<stdio.h>
int main()
{
int a[4];
int x, y, z, num;
scanf("%d", &num);
for (x = 1; x <= num; x++) {
scanf("%d", &a[x]);
int add = a[0] + a[4];
printf("%d\n", a[x]);
}
return 0;
}
From from your description it seems clear that you should not care for the numbers in between the first and the last.
Since you want to only add the first and the last you should start by saving the first once you get it from input and then wait for the last number. This means that you don't need an array to save the rest of the numbers since you are not going to use them anyway.
We can make this work even without knowing the length of the series but since it is provided we are going to use it.
#include<stdio.h>
int main()
{
int first, last, num, x = 0;
scanf("%d", &num);
scanf("%d", &first);
last = first; //for the case of num=1
for (x = 1; x < num; x++) {
scanf("%d", &last);
}
int add = first + last;
printf("%d\n", add);
return 0;
}
What happens here is that after we read the value from num we immediately scan for the first number. Afterwards, we scan from the remaining num-1 numbers (notice how the for loop runs from 1 to num-1).
In each iteration we overwrite the "last" number we read and when the for loop finishes that last one in the series will actually be the last we read.
So with this input:
4 1 5 5 1
we get output:
2
Some notes: Notice how I have added a last = first after reading the first number. This is because in the case that num is 1 the for loop will never iterate (and even if it did there wouldn't be anything to read). For this reason, in the case that num is 1 it is reasonably assumed that the first number is also the last.
Also, I noticed some misconceptions on your code:
Remember that arrays in C start at 0 and not 1. So an array declared a[4] has positions a[0], a[1], a[2] and a[3]. Accessing a[4], if it works, will result in undefined behavior (eg. adding a number not in the input).
Worth noting (as pointed in a comment), is the fact that you declare your array for size 4 from the start, so you'll end up pretending the input is 4 numbers regardless of what it actually is. This would make sense only if you already knew the input size would be 4. Since you don't, you should declare it after you read the size.
Moreover, some you tried to add the result inside the for loop. That means you tried to add a[0]+a[3] to your result 4 times, 3 before you read a[3] and one after you read it. The correct way here is of course to try the addition after completing the input for loop (as has been pointed out in the comments).
I kinda get what you mean, and here is my atttempt at doing the task, according to the requirement. Hope this helps:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int first, last, num, x=0;
int add=0;
printf("What is the num value?\n");//num value asked (basically the
index value)
scanf("%d", &num);//value for num is stored
printf("What is the first number?\n");
scanf("%d", &first);
if (num==1)
{
last=first;
}
else
{
for (x=1;x<num;x++)
{
printf("Enter number %d in the sequence:\n", x);
scanf("%d", &last);
}
add=(first+last);
printf("Sum of numbers equals:%d\n", add);
}
return 0;
}
in learning quick union algorithm, i have met these two statements
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
since I only learned for loop to be something like
for(i=0; i<100; i++)
I don't know the difference between the two statements and the following statements
i=p; i=id[i];
j=q; j=id[j];
i have no idea why the results are different?
thanks
I want to ask why
#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
is different from
#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
i=p; i=id[i];
j=q; j=id[j];
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
I have tested the results, that's why I am confused
i=p;
Sets i to the value of a variable p (defined and initialized elsewhere in the program)
i=id[i]
Sets i to the value of the i th element of the array id (defined and initialized elsewhere in the program)
for(i=p; i!=id[i]; i=id[i]);
Loop initializes i to the value of p, executes the statements inside the for loop once if i is not equal to the i'th value of the array id, and then stops.
Further explaination:
assuming some values for the variables:
int p = 4;
int i;
int id[5] = {1,2,3,4,5};
for(i=p; i!=id[i]; i=id[i]) {
printf("Loop executed!\n");
}
Output:
Loop executed!
And then a segmentation fault.
What happens:
i is set to 4, then compared to id[4]. This is unequal, thus the loop is triggered. After that it sets i to 5. Now it tries to compare id[5] to i. This is disallowed because id only has space for 5 elements and indexes start at 0.
When looking at non-standard for "loops" like this, it helps to convert your for loops into while loops. (that is all they really are)
To do that, remember that a for loops consists of three parts separated by semicolons. The initialization part, the conditional part, and the update or increment part:
for(initialize statement; boolean loop conditional; update/increment statement);
The initialize statement is executed before your loop, the loop conditional is evaluated to determine whether the loop continues, and the update/increment statement is executed as the end of the loop.
Your first example:
for(i=p; i!=id[i]; i=id[i]);
As a while loop, looks like..
i = p
while(i!=id[i]) {
i = id[i];
}
Your second example:
for(j=q; j!=id[j]; j=id[j]);
As a while loop, looks like..
j = q
while(j!=id[j]) {
j = id[j];
}
Once they're written like this, it's easier to tell what's going on.
We're initializing the loop variable to one of two values, p or q.
Then, we're looking into the array "id" at the location specified by the loop variable and updating the loop variable with it. This has the effect of looking up in the array the next loop variable. In other words, each slot in the array contains the next value to jump to.
The conditional checks to see whether the destination is the same as the current location. That is to say, if we are "told" to jump to the location we're already in.
The difference between you two loops is only the initialization value. The first one initializes to p where the second initializes to q.
It may be helpful to manually jump through a simple cases such as..
p=0
q=1
id = {1,2,2}
p=2
q=1
id = {0,0,2}
Output of the program:
#include <stdio.h>
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be printed: ",size);
while(i++ < size)
{
scanf("%d",&b[i]);
printf("%d %d\n", i, b[i]);
}
return 0;
}
for size = 5 and input numbers :
0 1 2 3 4
is
1 0
2 1
3 2
4 3
5 4
where first column is for i and second for elements of array b.
It is clear that i in the loop while(i++ < size) { incremented to 1 before entering the loop. This loop should have to store/print the value at/of b[1], b[2], b[3], b[4] but not b[5] as loop will terminate at i = 5.
How this code is printing the value of b[5]?
I have tested it for different array size and it is not printing any garbage value.
By reading and writing past the array, your program invokes undefined behavior. It doesn't mean that it has to crash or print garbage values, it can pretend working fine. Apparently, that's what is happening in this case.
In your loop, the condition i < size is checked before i is incremented. But, i is incremented before entering the body of the loop and not after it, so it is possible to access b[5] in this case, as i would be incremented after checking i < size with i=4. You do not want that, as this causes undefined program behavior.
If you try to access an element in the array which does not exist, e.g. array[size], you are accessing the next spot in the memory right after the array. In this case you are lucky, but if this meant you were accessing a part of the memory where your program isn't allowed to do so, you'd get a segmentation fault.
you could use a for cycle instead of a while so instead of while(i++<size)you could use for(i = 0; i < size; i++) that should solve your problem my friend :)