Why the output is "0 -6" and not "4 60"? Isn't k=8, l=2?
#define MAC(a,b) (a<b ? a*b:a-b)
void main (void)
{
int i=2;
int j=4;
int k=MAC(i,j);
int l=MAC(j,i);
i=MAC(k+l,k-l);
j=MAC(k-l,k+l);
printf("%d %d\n", i,j);
}
One immediate problem. The expression
MAC(k+l,k-l)
becomes
(k+l<k-l ? k+l*k-l:k+l-k-l)
^^^^^^^
and, as you can see from the underlined bit, the expression is not what you think it is due to the precedence rules (multiplication is done before addition).
This can be fixed by ensuring each argument in the macro is parenthesised:
#define MAC(a,b) ((a)<(b) ? (a)*(b):(a)-(b))
but that still won't help if you pass in something like n++ as it will be incremented multiple times.
Macros are very simple text substitutions and are well known to cause problems such as what you're seeing. My advice would be to turn MAC into a proper function that will avoid the problem completely, something like:
int mac (int a, int b) {
if (a < b)
return a * b;
return a - b;
}
#define MAC(a,b) (a<b ? a*b:a-b)
void main (void)
{
int i=2;
int j=4;
int k= i<j ? i*j:i-j;
int l= j<i ? j*i:j-i;
i= k+l<k-l ? k+l*k-l:k+l-k-l;
j= k-l<k+l ? k-l*k+l:k-l-k+l;
printf("%d %d\n", i,j);
}
This is what was produced after your code got preprocessed. preprocess macro happens before compilation. unlike compilation, there is no symbolic linking of variables that have occurred, but a mere 1 to 1 replacement of what you have defined.
Related
I am trying make sorting function for an array. I use selection sort in an ascending order but I have no ideas what's wrong with my "output" function and I know that this similar question have been asked on stack-overflow but the answers didn't help me much. The error on Dev C++ show like "[Error] a function-definition is not allowed here before '{' token".
#include<stdio.h>
#include<stdlib.h>
void sort(int arr[], int n)
{
int minindex;
int t,i,j;
for(i=0;i<n-1;i++)
{
minindex=i;
for(j=i+1; j<n; j++)
{
if(arr[minindex]>arr[j])
minindex=j;
}
if(minindex>1)
{
int t=arr[minindex];
arr[minindex]=arr[i];
arr[i]=t;
}
}
void output(int arr[], int n)
{
for(int i=0; i<n; i++)
{
printf("%5d", arr[i]);
}
}
int main()
{
int arr[]={1,3,5,7,9,2,4,6,8,0};
int*a=(int*)calloc(10,sizeof(int));
sort(a,10);
ouput(a,10);
getchar(); getchar();
return 0;
}
If you use CodeBlocks, you can goto Plugins->Source code formatter(AStyle) to auto-format your code. Don't know about DevC++.
Array name is a pointer itself to the location of the first array item in memory. No need to create int* (it is unused in your code)
Do not define a variable until it is being used.
To compare two files, run a diff style program on Linux (or open files up side by side in two windows). If you are on windows, you can use meld.exe.
main() goes before your functions. See function declarations before main(). It is considered better. Still better would be to move functions to another file.
Clicking on a brace '{' should highlight the corresponding brace in any IDE.
Poor indentation almost always exacerbates the missing brace problem.
I am tempted to give you the code, but I am sure you can do the edits yourself.
--- Output
0 1 2 3 4 5 6 7 8 9
Process returned 0 (0x0) execution time : -0.000 s
Press any key to continue.
I'm teaching my C with K&R this book, and got confused by the power function from 1.7 example.
Well, when I wrote the code exactly from the example given by the book on Code::Block and ran it, an error occurred: undefined reference to 'power'.
The codes are as follow:
#include <stdio.h>
#include <stdlib.h>
int power(int m, int n);
main ()
{
int i;
for (i = 0; i < 10; ++i)
printf("%d %d %d\n", i, power(2, i), power(-3, i));
return 0;
}
Is power function a predefined function provided by library? Because program above didn't define the body part of power
If so, why did I run into error? Did I include the wrong library?
The error message says that function power is not defined. I am sure that somewhere in the book there is the definition of the function or there is an exercise that requires that you write the function yourself.
It can be written simply. For example for positive n the function can look like
int power(int m, int n)
{
int result = 1;
for ( ; n; --n ) result *= m;
return result;
}
You can modify the function such a way that it would accept negative n.:)
Take into account that it would be much better if the function had return type long long int
For example
long long int power(int m, unsigned int n)
{
long long int result = 1;
for ( ; n; --n ) result *= m;
return result;
}
There is nothing called power() defined in standard C library. If you want a power() function, you have to write your own before using it.
If you want a library function, it is called pow(), defined in math library. Include the header file math.h, without having need to forward define the prototype. Also, don't forget to link against the math library using -lm.
Is power function a predefined function provided by library?
Answer: No. Power function is not predefined.
"Because program above didn't define the body part of power"
I made the same mistake by not checking the next page. See next page,you will find its(power function) definition.
Complete code-
#include <stdio.h>
int power(int m, int n);
/* test power function */
int main(){
int i;
for(i = 0; i < 10; ++i)
printf("%d %2d %3d", i, power(2,i), power(-3,i));
return 0;
}
int power(int base, int n)
{
int i, p;
p=1;
for(i=1;i<=n;++i)
p=p*base;
return p;
}
About error(s):
In my case i tried exactly the same code(except this line#include <stdlib.h>) as yours in geany editor and got-
gcc -Wall -o "pfunc" "pfunc.c" (in directory: /home/anz)
Compilation finished successfully.
if i try to compile from terminal with cc pfunc.c i get error(power undefined)
May be compiler issue? Anyway, im trying know the exact reason. Once i know i will edit.
Here I know that the following code simply copies the character i rather than its value to the preprocessor statement (which makes a error for undefined symbol i in compile-time).
What I want is:
Is their a way such that the compiler treats, i as a variable with some value rather than a character ?
#include <stdio.h>
#define PRINT(x) printf("%d \n", y ## x)
int main(void) {
int y1=0 , y2=1 , y3=4;
for(int i=1; i <= 3; ++i) {
PRINT(i);
}
return 1;
}
About the pre-processor
First of all, I think there's a need to clarify how the preprocessor works: it pre-processes the input files, which means it runs before the compiler. Unfortunatly, for historical reasons, it doesn't know anything about C or C++, doesn't parse anything, and just does very simple textual operations on words and parenthesis. Just to illustrate my point:
#define this __FILE__
#define file -- Hell no!
#define fine(a, b) fine: a ## _ ## b
Ok, so this is not a valid C or C++ file
But the preprocessor will run just fine(go, try!)
Run this with a pre-processor, for example gcc -x c -E -P test.txt and you'll get:
Ok, so "test.txt" is not a valid C or C++ -- Hell no!
But the preprocessor will run just fine: go_try!
So, obviously, when the preprocessor sees PRINT(i) in your code, it replaces it with printf("%d \n", yi) without thinking much about it. And it has absolutely no idea i is a variable, don't even think about evaluating it's value.
Solutions
Basically, what you want is print a bunch of numbers.
You could simply do
printf("0\n1\n4\n");
But this lacks makes changing numbers cumbersome,
so let's go with
printf("%d\n%d\n%d\n", 0, 1, 4);
Which makes it easy to change a number, but not to add/remove one.
Ok so how about:
printf("%d\n", 0);
printf("%d\n", 1);
printf("%d\n", 4);
Yeah, you can change/add/remove numbers easily but as any sane programmer you hate repetition. So, we need some kind of loop.
By far the simplest and most straightforward way to iterate in C is at runtime, using an array:
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/sizeof(int); ++i) {
printf("%d\n", y[i]);
}
If you want, you can hide the printf using a function:
inline void print_int(int* y, int i) { print_int(y[i]); }
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/4; ++i) print_int(y, i);
And going further with functions:
inline void print_int(int x) { printf("%d\n", x); }
inline void print_int(int* y, int i) { print_int(y[i]); }
inline void print_ints(int * y, int n)
{
for(int i = 0; i < n; ++i)
print_int(y, i);
}
template<int n> // C++
inline void print_ints(const int[n] & y) { print_ints(&y[0], n); }
int [] y = { 0, 1, 4 };
print_ints(y); // C++
// or in C:
print_ints(y, sizeof(y)/sizeof(int));
Now, what if you absolutely want the generated code to look like solution 3. ? This means you need the iteration to happen at compile-time. Tricky!
That's where the preprocessor can come into play. There are (hacky) ways to make it do this kind of things. I strongly recommend not implementing this yourself (except to play), but use the Boost.preprocessor library instead:
#define PRINTER(R,D, NUMBER) printf("%d\n", NUMBER);
#define NUMBERS (0, 1, 4)
BOOST_PP_LIST_FOR_EACH(PRINTER, _, BOOST_PP_TUPLE_TO_LIST(NUMBERS))
// will expand to printf("%d\n", 0); printf("%d\n", 1); printf("%d\n", 4);
Under standard C, this is not possible; during preprocessing, the compiler simply sees the identifier i as simply that - an identifier. It does not know that i is of type int, or that it's even a variable in the first place.
The easiest way to achieve what's intended is to use an array, like so:
int i;
int y[] = { 0, 1, 4 };
for (i = 0; i < 3; i++) // NOTE: arrays in C start at index 0, not 1
{
printf("%d \n", y[i]);
}
Also note that I got rid of the macro, as you want to use the value of a runtime variable i to select another runtime variable.
A fair warning — I'm very new to C, and there's some unpredictable behavior. I'm not sure how to begin troubleshooting this.
I'm trying to solve one of the early Euler problems (to do with numerical palindromes) and I'm having trouble with my check function. When a number a is passed through rev(a), everything works as it should. When passed through ret(a) (a function which will eventually check for equality, bool type, etc), it returns totally wrong number — something to do with memory, I think. Can anybody help me, please?
#include <stdio.h>
#include <stdbool.h>
int rev(int a);
int check(int a);
main() {
int a = 12;
printf("%i ", a);
printf("%i ", rev(a));
printf("%i\n", ret(a));
}
int ret(int a){
return rev(a);
}
int rev(int a){
int b;
while (a>0){
b = (b*10) + a%10;
a/=10;
}
return b;
}
In rev, the first iteration of the loop
int b;
while (a>0){
b = (b*10) + a%10;
operates on an uninitialised value of b. This makes the end result unpredictable and almost certainly wrong.
The fix is pretty simple - you just need to initialise b to 0
int rev(int a){
int b = 0;
// function unchanged beyond this
If calls to rev worked for you, this was just luck (either good or bad, depending how you look at it). Reading the content of uninitialised memory can have any effect, including the stack for b just happening to be set to 0. You'd probably have found that changing platform or compiler flags caused things to break.
I'm running into the following problem when trying to use concatenation with the C preprocessor:
#define substitute(id) var##id
int main()
{
int var0 = 999;
int var1 = 998;
int var2 = 997;
int var3 = 996;
int var4 = 995;
int i = 0;
for(i; i < 5; i++)
{
printf("Valor: %i \n", substitute(i));
}
system("PAUSE");
return 0;
}
Is there a way for the preprocessor to be able to read the value on "i" instead of just concatenating "vari"?
No. The preprocessor works before compilation and therefore before execution.
The define
#define substitute(id) var##id
will cause your loop to expand to:
for(i; i < 5; i++)
{
printf("Valor: %i \n", vari);
}
The preprocessor has no knowledge of the variable i, nor should it.
You should probably use an array:
int var[5] = {999,998,997,996,995};
and access it via []:
for(i; i < 5; i++)
{
printf("Valor: %i \n", var[i]);
}
That's not possible at the pre-processor stage because what you want depends on values that are only known later, at runtime.
What you need is an array and the index operator, var[i].
You need to be aware that the macro is resolved once (by the preprocessor) before the file is compiled, so at runtime, each iteration in the loop will render the same result when "calling" substitute.
Nope, because the preprocessor runs at compile time, not runtime, but you can use an array:
int vars[] = { 999, 998, 997, 996, 995 };
for (int i = 0; i < 5; ++i)
printf("Valor: %i \n", vars[i]);
No i is a runtime evaluation. There is no way for the preprocessor to know what the value of I could be.
Why would you do this with the preprocessor?
You seem to be trying to reinvent arrays:
int main() {
int var[] = {999, 998, 997, 996, 995};
int i;
for (i=0; i<5; i++)
printf("Valor: %i\n", var[i]);
return 0;
}
As many said - no, macros doesn't know anything about what's going on in program compile-time or run-time. But... if you wish you can generate some hackish code with macro which operates with stack directly (do not try this in home alone - it can blow your computer apart !! :-) )- define your macro as:
#define substitute(adr, max, id) *(adr + max - id)
and call like this:
printf("Valor: %i \n", substitute(&var4,4,i));
But keep in mind that this is just for curiosity, in real life it is not recommended to play directly with stack, because compiler may (and usually will) re-order variable allocation on stack and also you will risk some nasty bugs to happen and etc... So better as others said - make some array and operate on that.
hth!
C macros are only expanded at compile time and your printf line would become
printf("Valor: %i \n", vari);