This is a sample code just to show a different output from the LLVM compiler and the GCC. I wonder why? The answer should be very simple, but I can't see it.
(Xcode 4.6.1)
The code:
#include <stdio.h>
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
int increment() {
static int i = 42;
i += 5;
printf("increment returns %d\n",i);
return i;
}
int main( int argc, char ** argv ) {
int x = 50;
printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment()));
printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment()));
return 0;
}
The LLVM Output:
increment returns 47
increment returns 52
increment returns 57
max of 50 and 47 is 57
increment returns 62
increment returns 67
increment returns 72
max of 50 and 62 is 72
GCC Output:
increment returns 47
increment returns 52
max of 50 and 52 is 50
increment returns 57
increment returns 62
increment returns 67
max of 50 and 67 is 62
The order of evaluation of the parameters is not defined specified. So this:
printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment()));
causes undefined unspecified behavior . That's why you have different results on both compilers.
Another (potential) problem is: MAX - it could cause two calls to increment. Avoid using such macros.
The LLVM code produces the right results according to ANSI C. If you don't want increment to be called more than once per print statement, save the return value in a variable and use that. Mentally stepping through the code, the display should be
increment returns 47
increment returns 52
increment returns 57
max of 50 and 47 is 57
increment returns 62
increment returns 67
max of 50 and 62 is 72
So my initial reaction and study of the code was wrong, and the LLVM output is right. The reason for the LLVM result is that increment is called three times for each print statement in main. The way to make this code print sensible output is to save the value returned by increment in a variable and print the variable, not another call to increment. The difference in results doesn't depend on undefined behavior as far as I know, but on correct versus incorrect conformance to ANSI C.
Related
The level is basic so bear with me. There are a few similar topics but didn't find my luck there. What I'm trying to do is to find max element in a row and then put it in the place of last element of the same row, while the last element to be put in the place of the max one the program found.
So I've got this code in C, it's supposed to print the original array, do the magic and then print the modified array. It does find the max element in 1st row, puts it in the last place of the same row, but doesn't do the switch - the last element doesn't hop in the place of max element's. I know I did something dumb and plain simple, but I just can't find where the mistake is. Any help highly appreciated!
int main()
{
int a[3][4]={23,32,45,12,53,75,38,72,14,37,42,82}, i, j, t, l, max=a[1][0];
for(i=0;i<3;i++){
printf("\n");
for(j=0;j<4;j++){
printf("%d ", a[i][j]);
}
}
for(l=0;l<4;l++){
if(a[1][l]>max){max=a[1][l];}
}
t=a[1][3];
a[1][3]=max;
max=t;
for(i=0;i<3;i++){
printf("\n");
for(j=0;j<4;j++){
printf("%d ", a[i][j]);
}
}
return 0;
}
And here is what it returns (original array):
23 32 45 12
53 75 38 72
14 37 42 82
(modified array):
23 32 45 12
53 75 38 75
14 37 42 82
You also need to store the position of max:
int max_pos = 0; //same as the initial max - a[1][0]
for(l=0;l<4;l++){
if(a[1][l]>max){max=a[1][l]; max_pos=l;}
}
Then when you switch them:
t=a[1][3];
a[1][3]=max;
a[1][max_pos] = t;
I assume you are aware this only happens for the second row. If you want to do it for all rows, you'll have to store the positions in an array.
After i assign values to my array, and try to print its content using the for loop. The first few values of output are not the values assigned to the array.
input:-r 45 23 32 43 53 ed // these are the contents assigned to array
output:- ▒▒ 45 23 32 43 53 ed // i get that weird thing as my first value.
As the size of the array grows the more values that show up like that(▒▒).
How can i fix this so the output is as same as the input?
code used to print is as follows:
char **values = malloc(argc*sizeof(char));
for(c=1;c<=argc;c++){
printf("test value:%s\n",values[c]); // values contains the value
}
Arrays in C are zero-based.
Run your index from 0 to < argc:
for(c = 0; c < argc; ++c){
Don't use <= argc - 1 as this will give you trouble if argc is an unsigned type.
Also, don't read back the values in an array until you've assigned values to them. The behaviour on doing that is undefined in C.
#include<stdio.h>
int main() {
int i;
int vector[5]={6,17,28,39,410},*r; //variables declaration
r=(int*)&vector; //pointer declaration
for (i = 0; i<5;i++){ //print the array in using a loop
printf("%d ",vector[i]);
}
printf("\n\n");
for(i=0;i<5;i++){ //print the array in reverse order using a loop
vector[i] = *(r+4-i); //it should be from the last to the first but it prints it
printf("%d ",vector[i]); //differently, see below
}
return 0;}
It should be:
6 17 28 39 410
410 39 28 17 6
but it results in:
6 17 28 39 410
410 39 28 39 410
the last two should be 17 6
You are overwriting the data you're trying to read, before reading it.
Just write out the steps your code is taking manually, and you'll see it.
To do reversal in-place, you must swap values around, to avoid overwriting.
Also note that the name of an array evaluates to a pointer to the first argument, in the proper context. So this:
r=(int*)&vector;
is much better written as just:
r = vector;
You should really avoid casts, and your cast is completely unnecessary.
try this:
#include<stdio.h>
int main() {
int i;
int vector[5]={6,17,28,39,410},*r; //variables declaration
r=(int*)&vector; //pointer declaration
for (i = 0; i<5;i++){ //print the array in using a loop
printf("%d ",vector[i]);
}
printf("\n\n");
for(i=0;i<5;i++){ //print the array in reverse order using a loop
//it should be from the last to the first but it prints it
printf("%d ",*(r+4-i)); //differently, see below
}
return ( 0 );
}
In your code you are changing the first two values. So first two steps Your array
will be like this.
410 39 28 39 410
After that loop continues it will get that replaced value. You can store the replaced value in the another array.
for(i=0,j=4;i<j;i++,j--){
temp=vector[i]; // storing the value in temporary variable
vector[i] = r[j];
r[j]=temp; // assigning the value .
}
for ( i=0; i < 5 ; i ++ )
printf("%d\n",vector[i]);
I'm having trouble with a function to check if a number is prime - it's returning that a number is prime when it isn't sometimes (even numbers sometimes, too!). Any idea why?
int isPrime(long x){
int i;
if(x==2||x==3) return 1; //if i = 2 or 3, return true
if(!(x&1)) return 0; //if x is even return false
for(i=3;i<=sqrt(x);i+=2) if (x%i == 0) return 0; //if x is divisible by i return false
return 1;
}
To everyone, thanks so much for the answers, I'd +1 them all if my rep was high enough :D
Sadly, my idiocy has reached new heights, and I found the error was within logic elsewhere in my program.
Possibly it because of the rounding of the sqrt(x) as result of this function call is floating point value. So it can be a little less than rounded to the closest integer.
In this case e.g. sqrt(25) could be rounded to 4 instead of 5.
EDIT
The fault number on 104730 tells that
if(!(x&1)) return 0; //if x is even return false
doesn't seem to work correctly... So, can you try the x&1L?
I am not sure, but id the size of the int and long is different, and (probably) 1 is implicitly caste to a shorter one type, so possibly it checks incorrect bit...
Also try just
if(!(x%2)) return 0; //if x is even return false
in order to avoid bit patterns usage and platform dependence.
I edited the for-loop to:
for(i=3;i<=x/2;i+=1) if (x%i == 0) return 0;
In the main i go through the first 100 Numbers.
int main()
{
long test=0;
int i = 2;
for( ; i < 100; i++)
{
test = isPrime(i);
if(test == 1) printf("%d ",i);
}
getchar();
return 0;
}
This is the ouput:
and this ist the ouput for the first 100 primes:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
I changed the i+=2 to i+=1, because in your code the skip every second number.
You are not checking whether x is divisble by 2.
Before that for loop add a return 0 if its is divisble by 2.
OK so I am trying to get Pascal to read a set of integers from a input file then take the even numbers and add them together with in the range of 1-50. Not working for me. Here is what I have:
List of input file numbers
1 2 3 4 5 6 7 8 9 11 12 64 13 14 15 16 71 33 34 35 36 41 44 46 82 512 49 50
And my pascal program:
program even(input,output,indata);
uses crt;
Var
indata:text;
num, even:integer;
begin
clrscr;
assign(indata, 'j:\num.txt');
reset(indata)0;
read(indata, num);
while num>50 do
begin
read(indata, num);
if num mod 2=0 then
even:=even+num;
end;
writeln('Even sum is', even);
readln( );
end.
Any help would be great! When I run it I get text as "Even sum is 0".
You need to first fix your code so it will even compile. The line that calls reset has the 0 after the closing ), which is invalid syntax.
You need to first initialize your even variable, so that it contains a valid starting point.
Next, you need to fix the logic in your while loop. It's backwards. :-) You need to test for num < 50 if you want to stop at the end - the test you have now for num > 50 means that the loop will never execute, because the first value (1) ends the while loop.
This works in a plain console application in Delphi.
program Project2;
uses
SysUtils;
var
InData: Text;
num, even: Integer;
begin
AssignFile(InData, 'D:\TempFiles\numbers.txt');
reset(indata);
read(indata, num);
even := 0;
while num < 50 do
begin
read(indata, num);
if num mod 2 = 0 then
even := even + num;
end;
writeln('Even sum is ', even);
readln;
end.
It produces the output (which is correct according to the way your code is written, because it reads the value 64 inside the while num loop and therefore executes 1 time more than it should, and 64 is even so it gets added to even - I'll leave that for you to figure out). :-)
Even sum is 96.
Haven't done Pascal in a few decades, but if I recall:
You're saying:
while num > 50 do
and your first number is 1, so it just skips the loop and prints the initial value of 'even', which is 0.
You may have meant:
while num < 50 do
but even that will just exit at the first value 50 or greater.
If you mean to read all the numbers, but filter out those greater than 50, I think it's more like:
program even(input,output,indata);
uses crt;
Var
indata:text;
num, even:integer;
begin
clrscr;
assign(indata, 'j:\num.txt');
reset(indata)0;
(* read all of the numbers *)
while not eof(indata) do
begin
read(indata, num);
(* skip those greater than 50 *)
if num <= 50
begin
if num mod 2=0 then
even:=even+num;
end;
end;
writeln('Even sum is', even);
readln( );
end.
The previous posters have given good advice but I would add at the end (before end.)
CloseFile(infile) or Close(infile)
(depending on your version of Pascal). This will probably not affect the program output but is a good habit to get into for the future - if you're writing to (rather than reading from) a text file and don't close it, you may find some text is missing, or the file becomes unreadable.