I want to do something like this:
if([FUNCTION] > 3){
//do stuff
}
where FUNCTION is a function that performs some action and returns the result as an int. For example, function can be defined as:
a + 1;
return a;
where a was a previously defined variable. Is there any way to do this in C? Many thanks!
First of all
a + 1;
is a statement with no effect, so I'm assuming you meant a = a + 1. Then yes, you can of course call a function from within an if statement.
int foo(int* a) {
*a = *a + 1;
return *a;
}
// later ...
int a = 7;
if (foo(&a) > 3) {
// do stuff
}
If a is not known in the scope of the if statement, you probably meant something like this:
int a = 7;
int foo() {
a = a + 1;
return a;
}
// later ...
if (foo() > 3) {
// do stuff
}
Since grammatically, C allows if ( expression ) and a function call on the left of a relational expression with > is an expression as well, the answer is yes, you can do this in the straightforward way,
if (some_function() > 3) {
/* Do stuff. */
}
What kind of C book is it that doesn't make this clear? I highly recommend Kernighan, Ritchie, The C Programming Language, 2nd Edition (update for ANSI/ISO C89).
#include<stdio.h>
int a=5;
int foo(int a)
{
a++;
return a;
}
int main()
{
if(foo(a) > 3) {
printf("%d\n",a);
// Do stuff
}
return 0;
}
It's simple.
EDIT :It's just a demo source code to show that if condition returns true.
Related
Code snippet:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
The variable i is stored in stack every time when restart the loop ?
What is the memory structure when running this code ?
What is the behavior of this variable ?
It is a bad or good practice do this ?
Thanks.
You will never reach i == 500. It's being reset every time through the loop since it's within the scope of while(1){}.
The following will work.
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}
When a function runs in C, it allocates space for all the local variables its going to need. If the variables are allocated all next to each other at the top of the function its easy to see how it works:
void foo(){
int x;
int y;
y = 1;
x = y + 2;
return x + y;
}
If the variables are declared inside inner blocks of the function, what the compiler does is "lift" those variable declarations to the top of the function. If there are variables with clashing names, the compiler renames things for you so they reference the correct variable.
// This is what you write
void original(){
int x = 0;
while(1){
int x = 1;
}
}
// This is what the compiler "sees"
void lifted(){
int x1;
int x2;
x1 = 0;
while(1){
x2 = 0;
}
}
In your case, your code is behaving like this one:
void function(void)
{
int i;
while(1)
{
i = 0;
i += 1;
if(i == 500) break;
}
}
In this version, its clear that the i is being reset to 0 all the time, which is why the loop will run forever.
As for if declaring variables in inner scopes is a good practice or not, it doesn't have to do with memory usage but with the scope of your variable names. In general its a good thing to keep your variables confined to inner scopes if possible (for the same reason why local variables are preferred to global ones). That said, you always have to initialize your variables before the loop and not inside it. In this case, its about removing bugs and not about being a best practice.
Logically speaking, each iteration of the loop creates a new instance of the i variable which only exists within the body of the loop. As written, this code will never terminate, because each iteration of the while loop creates a new instance of i and initializes it to 0.
Attempting to reference i outside the body of the loop results in undefined behavior; IOW, code like
int *p;
while ( 1 )
{
int i = 0;
p = &i;
if ( some_condition )
break;
...
}
printf( "last value of i was %d\n", *p );
isn't guaranteed to do what you expect.
In practice, the generated machine code will set aside the space for i once at function entry; however, you should not rely on that behavior.
The variable i will always be at 0 or 1 in this code; the break will never execute.
The variable i is declared in and is local to the while loop.
In the C language, a pair of braces can create a new scope
that hides variables with the same name declared outside the
scope.
This code:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
should be changed to this:
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}
When I compile this code I get an error "in front of int val, there isn't" ;
how can I get rid of this error?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char card_name[3];
puts("카드 이름을 입력하세요: ");
int val = 0;
if(card_name[0]=='K') {
val = 10;
}
else if (card_name[0] == 'Q') {
val = 10;
}
else if (card_name[0] == 'J') {
val = 10;
}
else if (card_name[0] == 'A') {
val = 11;
}
else
{
val = atoi(card_name);
}
printf("카드값은 다음과 같습니다 : %i/n", val);
return 0;
}
Declare all variables in the top of main just after { ,i.e, declare val before the first puts. It is because your compiler uses C89 which forbids mixed declarations and code. From C99 onwards , they can be declared (almost) anywhere.
As mentioned in other answers, C89 does not support declaring variables other than at the start of the block. If you are using clang or gcc, you might want to add '-std=gnu99' to your CFLAGS. If using another compiler or an IDE, look for the language and change it to C99 or higher.
It seems that the compiler requires that all definitions of varaibles would be in the beginninh of block.
Try to write
char card_name[3];
int val = 0;
puts("카드 이름을 입력하세요: ");
Also take into account that array card_name is not initialized.
I was trying to do two things
Get a dynamic backward slice based on a criteria.
Map the slices statements back to the actual source code.
Problem 1: The slice returned by Frama-C doesn't return the exact statements that were relevant for the criteria - mainly the if and else statements.
Problem 2: How do I map the slicing statements back to the source code? The program gets changed when slicing (for example : int a=9 becomes 2 statements in sliced code int a; and a = 9;.) I am ok with the slice but what is the information I can use to map these back to the statements in the source code.
This is the source code.
void main(){
int ip1 = 9;
int ip2 = 3;
int option = 1;
int result = math(option,ip1,ip2);
//# slice pragma expr ((option == 1) || !(result == (ip1+ip2)));
}
int math(int option, int a, int b){
int answer = 0;
if (option == 1){
answer = a+b;
}else{
if (option == 2) {
answer = a-b;
}else { // a ^ b
for(int i=0 ;i<b; i++){
answer=answer*a;
}
}
}
return answer;
}
I use the following command to get the slice.
frama-c t.c -slicing-level 3 -slice-pragma main -slice-print
The slice I get from frama-c is :
void main(void)
{
int ip1;
int ip2;
int option;
int result;
ip1 = 9;
ip2 = 3;
option = 1;
result = math_slice_1(ip1,ip2);
/*# slice pragma expr option≡1∨!(result≡ip1+ip2); */ ;
return;
}
int math_slice_1(int a, int b)
{
int answer;
answer = a + b;
return answer;
}
Problem 1:
I dont get the if and else conditions in the slice. What should I do to get them?
I expected the following slice:
int math_slice_1(int a, int b)
{
int answer;
if (option == 1){
answer = a + b;
}
return answer;
}
Problem 2:
Source code has : int ip1 = 9;
But the sliced code has :
int ip1;
ip1 = 9;
How to map these 2 sliced statements back to the source code statement.
For Problem 1, the test is sliced out because it is always true since option is set to 1 in the main function. If you want to keep the test, you have to make option an entry (either external global variable or a parameter of main for instance), but then, there will be nothing to slice in the math function... The slicing tries to keep only what is strictly necessary, and the test is not in your case.
I need to create a recursive function that receives a number by two without using /.
This is what I wrote, but it works only if after dividing it will still be a decimal number and not a float, that's why I asked.
int recursive(int a, int b){
if ( a == (0.5 * b) )
return a;
return recursive(a-1, b);
}
Btw, the function can receive only 1 parameter not 2 or more :/
I think you need something like this
int divide(int a, int b){
if(a - b <= 0){
return 1;
}
else {
return divide(a - b, b) + 1;
}
}
This divides by two using repeated subtraction and recursion.
int divide_by_two(int a) {
if (a < 0) return -divide_by_two(-a);
if (a < 2) return 0;
return 1 + divide_by_two(a - 2);
}
Generalising, this divides a by b using repeated subtraction and recursion.
int divide(int a, int b) {
if (a < 0) return -divide(-a, b);
if (b < 0) return -divide(a, -b);
if (a < b) return 0;
return 1 + divide(a - b, b);
}
Note, these functions don't round exactly the same way that division is defined to do in C.
You can try this, it should work:
int dividebytwo (int a){
static int answer = 0;
if (a < 0){
if ((answer * 2) > a){
answer --;
return dividebytwo (a);
}
return answer;
} else if (a > 0){
if ((answer * 2) < a){
answer ++;
return dividebytwo (a);
}
return answer;
}
return 0;
}
The trick here is using the static attribute. The static attribute means that the variable is only initialized once and retains its value after every function call. Really, you're using two parameters but it looks like you're only using one.
The only downside to this function is that you can only count on it to work more than once. Since this is probably for a simple homework assignment, it probably doesn't matter. But in reality, this is considered hugely inefficient and unreliable.
To compensate for the only-works-once factor, may add one of these fixes:
declare answer as a global variable and set it to 0 before every function call.
append return answer = 0; to the end of the function, instead of return 0;. This is so that whenever you want to call it again, you would call it beforehand as dividebytwo (0);.
I also cannot stress enough how weird of a concept this is, it sets of all sorts of red flags for anyone who practices careful programming - could be why you're getting so many downvotes. So use with caution!
#include<stdio.h>
int divide(int a, int b){
if( a-b < 0)
return 0;
else if ( a-b == 0)
return 1;
else {
return divide(a-b, b) + 1;
}
}
http://codepad.org/o4CoiaON
in the following simple reverse function I'm always off by one, meaning the first character passed in is never printed last like it should be:
void reverse(char * c)
{
if(*c != '\0')
{
reverse(++c);
printf("%c", *c);
}
else {
return;
}
}
yet when I change the call to reverse to be c+1, everything works fine. Any ideas as to why, the unary pre-increment operator should be doing exactly the same as c + 1. I know a recursive function isn't the best performing way to go about this problem but I'm just experimenting at the moment. Thanks!
Because c+1 does not change c whereas ++c does.
Think about this when c is pointing to address 1234:
reverse(++c); // c is now 1235 and you pass that.
printf("%c", *c); // so we print the second character at 1235.
With the c+1 version:
reverse(c+1); // c is still 1234 but you pass 1235.
printf("%c", *c); // so we print the first character at 1234.
For what it's worth, your reverse function is needlessly complicated.The else return is redundant and I personally prefer recursion calls that check terminating conditions first since I've often found these are usually easier for compilers to do tail-end recursion optimisations on.
The following complete test program shows you the way I'd do it:
#include <stdio.h>
void reverse (char *c) {
if (*c == '\0') return;
reverse (c + 1);
putchar (*c);
}
int main (int argc, char *argv[]) {
int i;
for (i = 1; i < argc; i++) {
reverse (argv[i]);
putchar ('\n');
}
return 0;
}
Running this with testprog hello goodbye gives you:
olleh
eybdoog
No the unary pre-increment is not the same like addition by one.
f(++c) is equivalent to
c = c + 1
f(c);
whereas f(c+1) is equivalent to
auto d = c + 1;
f(d);
And just for completeness: f(c++) is the same like
f(c);
c = c+1;
However sequence points matter, e.g. if(c++ > 0 && c++ < 10) would evaluate like
auto a = c;
c = c + 1;
auto b = c;
c = c + 1;
if(a > 0 || b < 10) { /* ... */ }
and consequently preincrement
c = c + 1;
auto a = c;
c = c + 1;
auto b = c;
if(a > 0 || b < 10) { /* ... */ }
Calling with c + 1 won't change the value of c in the local context (the one used when printing *c), but using ++c in the call will.
No, it doesn't do the same thing.
It increments it then sends it to your function.
when you put c+1, it doesn't change the value of c, but ++c does change the value of c.. as an example for difference between pre and post increment operators:
int a = 1;
int b = ++a;
// Now a is 2 and b is also 2.
int a = 1;
int b = a++;
// Now a is 2 but b is 1.
FIXED: You shouldn't use increment operator. Operator+ would be better.:
reverse(c + 1);
printf("%c", *c);