I want to print the value as well as its type
Input:
1
3
5
78
10
Output:
Odd 1
Odd 3
Odd 5
Even 78
Odd 11
#include <stdio.h>
int main()
{
int a[4],b,c;
for(b=0 ; b<=4 ; b++)
{
scanf("%d",&a[b]);
}
for (c=0 ; c<=4 ; c++)
{
switch (a[c]%2)
{
case 0 :
printf ("Even %d\n",a[c]);
break;
case 1 :
printf ("Odd %d\n",a[c]);
break;
}
}
return 0;
}
Why is the last output Odd 11 instead of Even 10?
You only have to change the declaration of a[4] into a[5] for having a correct program. The boundaries of the iterations are correct.
What happens when you run your code is that the four first input values go into the array a[4] and the fifth one into the variable b which is allocated immediately behind the array, in your case. This is a programming error and gives unpredictible results, depending on how the compiler is allocating memory.
In your case, we can conclude that the variable b is stored behind the array a[4], and is incremented once after you store the fifth element into what you think is the array. The place where this happens is the b++ statement of the for loop.
I couldn't reproduce this behaviour because my compiler probably doesn't allocate b immediately behind a[4].
You made the array of the size 4 but you are entering 5 values in it.
So you could just increase the array size or make the loop enter 4 values by exchanging <= with < sign.
Hope it helps.
You are entering five numbers, not four. Change int a[4] to int a[5]. Then optionally change all your conditions to <5 for clarity, as this is usually what C programmers expect.
Related
Hey I am trying to understand pointers and I create a program in which I give words from keywords and I
store them in an array and after that I want to print the first character of the first word (I expected) but it prints the first character of the second word
What is going wrong?
#include<stdio.h>
#include<stdlib.h>
int main ()
{
int i=0;
char array[5][10];
for(i = 0 ; i < 5 ; i++)
{
gets(array[i]);
}
printf("\n");
char *p;
p=&array[0][10];
printf("%c",*p);
return 0;
}
The position in the array you are looking for doesn't exist, so the program is showing a random value.
The arrays go from 0 to (n-1), 'n' being 5 or 10 in your case. If you search a differente position in the range of the array you will find the correct answer.
Try changing this part of the code ('a' have to be a value from 0 to 4 and 'b' have to be a value from 0 to 9)
p=&array[a][b];
pointer are address in memory
1rst word adresses are from 0 to 9
2nd word from 10 to 19
p=&array[0][10]; points to the 10th elt so the first letter of the second word! and not for a random value as previous post suggests.
That said NEVER use gets
Why is the gets function so dangerous that it should not be used?
Problem : Although I declared two char strings , whose contents are the same , Outputs are different.
#include <stdio.h>
int main(void)
{
/* Initialization of two different array that We deal with */
char arr1[10]={'0','1','2','3','4','5','6','7','8','9'};
char arr2[10]="0123456789";
/* Initialization End */
for(int i = 0 ; i < 11 ; ++i)
{
printf("arr1[%d] is %c \t\t",i,arr1[i]);
printf("arr2[%d] is %c\n",i,arr2[i]);
if(arr1[i]=='\0')
printf("%d . character is \\0 of arr1 \n",i);
if(arr2[i]=='\0')
printf("%d . character is \\0 of arr2 \n",i);
}
return 0;
}
Expectation : I expected that both if statements are going to be true for any kind of value of 'i'.
Output : It is an output that I got it.
arr1[0] is 0 arr2[0] is 0
arr1[1] is 1 arr2[1] is 1
arr1[2] is 2 arr2[2] is 2
arr1[3] is 3 arr2[3] is 3
arr1[4] is 4 arr2[4] is 4
arr1[5] is 5 arr2[5] is 5
arr1[6] is 6 arr2[6] is 6
arr1[7] is 7 arr2[7] is 7
arr1[8] is 8 arr2[8] is 8
arr1[9] is 9 arr2[9] is 9
arr1[10] is 0 arr2[10] is
10 . character is \0 of arr2
Both cases invoke undefined behavior by accessing the array out of bounds. You cannot access index 10 of an array with items allocated from index 0 to 9. Therefore you need to change the loop to i<10 or anything might happen. It just happened to be different values printed - because you have no guarantees of what will be printed for the byte at index 10.
In both examples, there is no null terminator, so they are equivalent. Due to a subtle, weird rule in the C language (C17 6.7.9/14 emphasis mine):
An array of character type may be initialized by a character string literal or UTF−8 string
literal, optionally enclosed in braces. Successive bytes of the string literal (including the
terminating null character if there is room or if the array is of unknown size) initialize the
elements of the array.
Normally when trying to store too many initializes inside an array, we get a compiler error. But not in this very specific case with a string literal initializer, which is a "language bug" of sorts. Change to char arr2[9]="0123456789"; and it won't compile. Change to char arr2[11]="0123456789"; and it will work just fine, even when iterating over 11 elements.
There are a few small things wrong with your code and the assumptions you seem to make about it.
1. These two declarations are not the same
char arr1[10]={'0','1','2','3','4','5','6','7','8','9'};
char arr2[10]="0123456789";
The second line is equal to this:
char arr2[10]={'0','1','2','3','4','5','6','7','8','9', 0x00};
... which defines an array containing 11 elements. Check out implicit zero-termination for string literals.
EDIT:
I'm getting quite a lot of down-votes for this point specifically. Please see Lundin's comment below, which clarifies the issue.
2. Your for-loop iterates over 11 elements
for(i=0 ; i<11 ;++i)
The loop above goes through i = 0..10, which is 11 elements.... but you only wanted to compare the first 10 right?
You could change your loop to only compare the first ten elements [for(i = 0; i < 10; ++i)] and that would make your program work as you expect.
Because of what it seems you are assuming, I would recommend reading up on strings in C, array-indices and undefined behavior.
when a character array is initialized with a double quoted string and array size is not specified, compiler automatically allocates one extra space for string terminator ‘\0’
Ref
#include <stdio.h>
int main(void) {
int n,i;
int str[n];
scanf("%d\n",&n);
for(i=0;i<=n;i++)
{
scanf("%d",&str[i]);
printf("%d th %d\n",i,n);
}
return 0;
}
Input:
10
8 9 2 1 4 10 7 6 8 7
Output:
0 th 10
1 th 10
2 th 10
3 th 10
4 th 10
5 th 10
6 th 10
7 th 6
Why is 6 in the output?
This is really strange code with undefined behavior. What do you expect this:
int n; // No value!
int str[n];
To do? You get an array whose length is unknown since n has no value at the point of the str declaration.
If you expected the compiler to "time-travel" back to the str[n] line magically when n is given a value by scanf(), then ... that's not how Co works, and you should really read up on the language a bit more. And compile with all warnings you can get from your environment.
As an extra detail, even if it were fixed so that n had a value, the for loop overruns the array and gives you undefined behavior again.
For an array of size m, the loop header should read
for (size_t i = 0; i < m; ++i)
Since indexing is 0-based, you cannot index at m, that's outside the array.
In your code
int n,i;
int str[n];
you're using n while it has indeterminate value, unitialized. It invokes undefined behavior.
To elaborate, n being an automatic local variable, unless initialized explicitly, contains indeterminate value.
Solution: You need to define int str[n]; after you has taken the value from user (and sanitized).
After that, there's once more issue, your loop runs off-by-one for the array. C uses 0-based array indexing, so, for an array of size n, the valid indexes will be 0 to n-1. You loop construct should be
for(i=0; i<n; i++)
The value for the size of the string str[] is not yet defined. You need to have initialized this value before declaring a string/array.
If you're using gcc to compile, try including the -Wall flag in your compile line to catch errors like this.
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 :)
I'm just a beginner at C.
I'm trying to make a simple program to arrange the user-entered digits in ascending order. I have figured out the solution but can't understand why my other code wouldn't work :(
-------------------------------------------------------------------------
working code:
-------------------------------------------------------------------------
#include <stdio.h>
int main()
{
int i,j,num[10];
printf("Enter 10 numbers\n");
for (i=0;i<10;i++)
{scanf("%d",&num[i]);}
for (i=0;i<9;i++)
{
for (j=i+1;j<10;j++)
{
if (num[i]>num[j])
{
num[i]+=num[j];
num[j]=num[i]-num[j];
num[i]=num[i]-num[j];
}
}
}
printf("The numbers in ascending order are:");
for (i=0;i<10;i++)
{
printf(" %d",num[i]);
}
return 0;
}
-------------------------------------------------------------------------
code that won't work:
-------------------------------------------------------------------------
#include <stdio.h>
int main()
{
int i,j,num[10];
printf("Enter 10 numbers\n");
for (i=1;i<=10;i++)
{scanf("%d",&num[i]);}
for (i=1;i<10;i++)
{
for (j=i+1;j<=10;j++)
{
if (num[i]>num[j])
{
num[i]+=num[j];
num[j]=num[i]-num[j];
num[i]=num[i]-num[j];
}
}
}
printf("The numbers in ascending order are:");
for (i=1;i<=10;i++)
{
printf(" %d",num[i]);
}
return 0;
}
In the latter program, numbers appear out of order, and there even are numbers that haven't been entered.
My question is, isn't it basically the same code? Just that in the latter program numbers would be stored from num[1] to num[10] instead of num[0] through num[9]?
Does it have something to do with array definitions?
It seems I have serious misconceptions, please help me out!
In C, when you have int num[10];, your indexes need to go from 0 to 9, never to 10. So look over your code, if any i or j ends up with a value of 10 any time during the program run, that's bad news.
Indexes in C go start from 0. so when you declare an array of size 10, and you try to get element at index 10, you're actually getting the 11th element. Since you haven't defined the 11th element, the array will most likely get some random numbers from memory, which is why you are noticing numbers you have note entered.
Since you are new to programming, I would suggest taking the time now to really learn about how C manages memory, and how different data structures access the memory. It might be a little boring now, but you'll save yourself some headaches in the future, and you will start to build good habits and good practices, which will lead to writing good, optimal code
for(i=0;i<9;i++) //**i<9**
for (j=i+1 ...)
If i=8 then j=9 , everything is OK.
In second code snippet:
for(i=0;i<10;i++) //**i<10**
for (j=i+1 ...)
If i=9 then j=10, so you try to access num[10] and it gives you error.
If you want to access num[10] then you must declare array int num[11] and then you can access num[10].
Array Basics
int num[10]
Capacity of array = 10
Every element of this array are integer.
First element index is 0. So If you want to access first element , num[0]
Last element index is 9. So If you want to access last element, index must be length of array - 1 , so num[9]
There are 10 elements in the array and they are :
num[0] , num[1] , num[2] , num[3] , num[4] , num[5] , num[6] , num[7] , num[8] and num[9]
You can learn further at http://www.cplusplus.com/doc/tutorial/arrays/
In your non-working example, you have invalid memory accesses. For example, when i = 9 and j = 10, you access num[10], which is invalid memory.
Welcome to programming! I believe you are a bit confused about how arrays are indexed in C.
Arrays in most languages (including C) are known as zero-indexed arrays. This means the start of an array is always at position 0. So if you make int num[10], trying to access num[10] isn't actually a valid call at all, because the start is num[0]. Hence you can only access from num[0] to num[9].
It's an easy mistake to make, even though I've been programming for years sometimes when it's been a long night I'll still make silly array indexing issues.
In your other code example, you were doing this:
int num[10];
for(int i = 1; i <= 10; i++) {
//...
}
That means you have an array with ten spaces [0-9], and for the last part of your for loop, you were trying to access num[10] which doesn't exist.
Your working example goes from 0-9 and never tries to read num[10], so it works.
Arrays in C, as in most languages, start with position 0 and count that as position one. So the last element of your array would be the size you entered when you declared the variable, minus one.