Say I have an if/else statement and also some code that should execute in either case. I can put the "common" code in each block, or I can put it after the statement, e.g.:
if (x)
{
i++;
k++;
return;
}
else
{
j++;
k++;
return;
}
or
if (x)
{
i++;
}
else
{
j++;
}
k++;
return;
Is there a difference in performance between the two methods? If so, which one is faster, and why?
Related
I'm cross-compiling using ARM/GNU C Compiler:6.3.1 with optimizations -O0. A simple function like this:
static uint8_t xyzzy(void) {
if (<predicate one>) {
return 1;
} else if (<predicate two>) {
return 2;
} else {
return 4;
}
}
results in an error message:
Error control reaches end of non-void function [-Werror=return-type]
Is it really the case that the compiler doesn't know that one of those return statements must always be executed? Or is it me that is confused? And what is a recommended fix?
(P.S.: No, this is not a duplicate of Control reach end of non-void function, since I do have an else as the last clause.)
Simply add a return statement at the end of your function. GCC considers that your function doesn't have a return statement.
static uint8_t xyzzy(void)
{
if (<predicate one>) {
return 1;
} else if (<predicate two>) {
return 2;
} else {
return 4;
}
return 0; // This will never be reached
}
You can get rid of unnecessary {}s and the elses:
static uint8_t xyzzy(void)
{
if (<predicate one>)
return 1;
if (<predicate two>)
return 2;
return 4; // Executed if none of the above conditions are met.
}
I am trying to use some static analysis tools to check a program with extensive usage of recursive calls. Conceptually, it is something like this:
int counter = 0;
int access = 0;
extern int nd (); // a nondeterministic value
void compute1();
void compute2();
int get()
{
static int fpa[2] = {2, 2}; // each function can be called for twice
int k = nd() % 2;
if (fpa[k] > 0) {
fpa[k]--;
return k+1;
}
else
return 0;
}
void check_r(int* x) {
if (x == &counter) {
__VERIFIER_assert(!(access == 2));
access = 1;
}
}
void check_w(int* x) {
if (x == &counter) {
__VERIFIER_assert((access == 0));
access = 2;
}
}
void schedule() {
for (int i = 0; i < 5; i++) {
int fp = get();
if (fp == 0)
return;
elif (fp == 1)
compute1();
elif (fp == 2)
compute2();
}
}
void compute1()
{
// some computations
...
schedule(); // recursive call
check_w(&counter); // check write access
...
}
void compute2()
{
// some computations
...
schedule(); //recursive call
check_r(&counter);
...
}
int main()
{
schedule();
return 0;
}
My tentative tests show that due to the recursive call, the static analysis becomes too slow to terminate.
While in principle, I can somehow rewrite the recursive call into a switch statement or so, but the problem is that before the recursive call schedule, compute1 and compute2 functions have performed nontrivial amount of computations already, and it is difficult to save the program context for further usage.
I have been trapped to optimize this cases for a few days, but just cannot come up with a even ad-hoc solution. Could anyone please provide some comments and suggestions to get rid of the recursive call here? Thank you so much.
To me it looks like all the schedule function is doing is deciding whether to call compute1 or compute2 and all the get is doing is ensuring a single function is never called more than twice. I don't think the recursive call from compute to schedule is necessary then since there is never more than two calls. The recursion here seem to imply that every time we can successfully call one of the compute functions we wan't another chance to call compute again
void schedule() {
int chances = 1;
for (int i = 0; i < 5 || chances > 0; i++) {
int fp = get();
if (fp == 0){
chances--;
if(chances < 0)
chances = 0;
continue;
}
elif (fp == 1){
compute1(); chances++;
}
elif (fp == 2){
compute2(); chances++;
}
}
}
void compute1()
{
// some computations
...
//schedule(); remove
check_w(&counter); // check write access
...
}
void compute2()
{
// some computations
...
//schedule(); remove
check_r(&counter);
...
}
This code is a bit confusing so please clarify if I made any incorrect assumptions
I am absolutely HORRIBLE at passing functions, and even more so with passing arrays.I've problem with my code, I use Quick Sort for sorting my data from External File. The Function can't passing the sort result.
UPDATE : The Function can passing the sort but, sorting in small to big, I want sort big to small , how to do that ?
But if I use simple sorting Like
int temp_score;
string temp_name;
for(int j=0;j<100;j++)
{
for(int k=0;k<100;k++)
{
if(score[j]>score[k])
{
temp_score=score[j];
score[j]=score[k];
score[k]=temp_score;
temp_name=name[j];
name[j]=name[k];
name[k]=temp_name;
}
}
}
No problem with simple sorting.
void quicksort(int score[],string name[],int kiri,int kanan){
int temp_score=0,i=kiri,j=kanan;
int pivot = score[(kiri+kanan)/2];
string temp_name;
//Pengurutan data berdasar Pivot
while (i <= j){
while (score[i]<pivot){
i++;
}while (score[j]>pivot){
j--;
}if (i <= j){
temp_score=score[i];
score[i]=score[j];
score[j]=temp_score;
temp_name=name[i];
name[i]=name[j];
name[j]=temp_name;
i++;
j--;
}
}
//Rekursif
if (kiri<j){
quicksort(score,name,kiri,j);
}if (i<kanan){
quicksort(score,name,i,kanan);
}
}
int main (){
string name[100];
int score[100];
int i=0;
for (int i=0;i<100;i++)
{
name[i]="";
score[i]=0;
}
ifstream highscore;
highscore.open("highscore.txt");
while(!highscore.eof())
{
getline(highscore,name[i]);
highscore >> score[i];
highscore.ignore(100,'\n');
i++;
}
quicksort(score,name,0,99);
cout<<"\tNAMA\t\t|\t\tSCORE\t\t"<<endl;
cout<<"========================================================"<<endl;
for(int m=0;m<25;m++)
{
cout<<name[m]<<"\t\t\t\t"<<"Rp "<<score[m]<<endl;
}
}
To sort in descending order, you would generally replace '<' with '>', i-- with i++, limits are reversed - and I mean as a general guideline, not literally replace blindly everywhere. Ex:
int temp_score;
string temp_name;
for(int j=0;j<100;j++)
{
for(int k=0;k<100;k++)
{
if(score[j]<score[k])
{
temp_score=score[j];
score[j]=score[k];
score[k]=temp_score;
temp_name=name[j];
name[j]=name[k];
name[k]=temp_name;
}
}
}
You can follow this guideline in your other code.
EDIT: Here is a snippet from your code the way you want. Note that I have inserted dummy data instead,
http://ideone.com/KAs1fG
Incorporate this in your code.
How To sort in descending order ?? I so confused
void quicksort(int score[],string name[],int kiri,int kanan){
int temp_score=0,i=kiri,j=kanan;
int pivot = score[(kiri+kanan)/2];
string temp_name;
//Pengurutan data berdasar Pivot
while (i <= j){
while (score[i]<pivot){
i++;
}while (score[j]>pivot){
j--;
}if (i <= j){
temp_score=score[i];
score[i]=score[j];
score[j]=temp_score;
temp_name=name[i];
name[i]=name[j];
name[j]=temp_name;
i++;
j--;
}
}
//Rekursif
if (kiri<j){
quicksort(score,name,kiri,j);
}if (i<kanan){
quicksort(score,name,i,kanan);
}
}
Below is my solve method. When I call it in my main method, nothing happens and all the succeeding it is not executed but no error is reported by eclipse.
public boolean solve(int r, int c){
if(c>8){
c=0;
r++;
}
if(r>8){
return true;
}
while(table[r][c].value!=0){
c++;
if(c>8){
c=-0;
r++;
}
if(r>8){
return true;
}
}
for(int k=1;k<10;k++){
if(table[r][c].checkRow(k)&&table[r][c].checkCol(k)&&table[r][c].checkCube(k)){
table[r][c].value=k;
solve(r,c);
}
}
table[r][c].value=0;
return false;
}
Will this algorithm backtrack? If not, why?
It looks like a logical error and hence eclipse does not report anything.
In for loop section of your code, you should have something like this
for(int k=1;k<10;k++){
if(table[r][c].checkRow(k)&&table[r][c].checkCol(k)&&table[r][c].checkCube(k)){
table[r][c].value=k;
if(solve(r,c)){
return true;
}
table[r][c].value=0;
}
}
In your case you are un-assigning the table outside the for loop, which prevents the code from backtracking.
Here is my code for solving sudoku. Hope it helps.
I found an implementation of the Morris tree traversal,
It works fine,,, but having a bit of a problem trying
to traverse the tree in reverse order.. -
void MorrisTraversal(struct Node *root)
{
struct Node *p,*pre;
if(root==0) { return; }
for(p=root;p!=0;)
{
if(p->Left==0) { printf(" %d ",p->Data); p=p->Right; continue; }
for(pre=p->Left;pre->Right!=0 && pre->Right!=p;pre=pre->Right) { }
if(pre->Right==0)
{ pre->Right=p; p=p->Left; continue; }
else
{ pre->Right=0; printf(" %d ",p->Data); p=p->Right; continue; }
}
}
By reverse order, I'm assuming you mean reverse inorder traversal. You have at least two options:
You could modify the code and swap all the ->Right pointer references with ->Left ones.
You could replace the two printf statements with pushes onto a stack. Once the algorithm completes, you would then pop off the data from the stack to print them. This however defeats the whole purpose of the Morris traversal algorithm, which was to be stackless.
This related SO thread might help you understanding.
I hope this helps.
Here is one sample in Java. Click Here for one more sample using iteration instead of recursion.
public int depthOfTree(TreeNode node){
if(node == null){
return 0;
}
int leftDepth = depthOfTree(node.left);
int rightDepth = depthOfTree(node.right);
if(leftDepth > rightDepth){
return leftDepth+1;
} else {
return rightDepth+1;
}
}
//Reverse Level with recursion
public void reverseLevelOrder(TreeNode node){
int depth = depthOfTree(node);
for(int i=depth;i>0;i--){
printTree(node,i);
}
}
public void printTree(TreeNode node, int level){
if(node == null){
return;
}
if(level == 1){
System.out.print(node.data+" ,");
} else if(level>1){
printTree(node.left, level-1);
printTree(node.right, level-1);
}
}