Showing posts with label C Language. Show all posts
Showing posts with label C Language. Show all posts

Thursday, 28 December 2017

Print a Range of a char Array without a for Loop

Code:
#include <stdio.h> 
 int main() 
   char a[1024] = "abcdefghijklmnopqrstuvwxyz";  
   printf("Characters 0 through 2 of a[]: %.3s\n", a); 
   printf("Characters 10 through 15 of a[]: %.6s\n", &a[10]); return 0; 
}

Prints this:
Characters 0 through 2 of a[]: abc 
Characters 10 through 15 of a[]: klmnop

The "%.Ns" notation in the printf string is "%s" with a precision specifier. It's buried in the geek-speak in the printf(3) man page


ref:
https://www.linuxquestions.org/questions/programming-9/is-there-a-way-to-print-a-range-of-a-char-array-without-a-for-loop-842798/

Thursday, 7 December 2017

Casting Bitwise struct to Integer

I have bitwise structure with a bunch of flags.

struct {
  uint8_t a: 4; 
  uint8_t b: 4; 
} _tVarA

_tVarA Var_A = {0,0};

But when I want to view them as a whole integer, I need to cast it like this:
                               *(uint8_t*)&Var_A

ref:
http://www.avrfreaks.net/forum/casting-bitfield-struct-integer
https://stackoverflow.com/questions/11903820/casting-struct-into-int

Monday, 4 December 2017

STATIC Variables and Functions in C




ref:
http://www.jianshu.com/p/f413ba3b2728
http://www.cnblogs.com/wly603/archive/2012/04/11/2442065.html
http://bbs.csdn.net/topics/350238100
http://www.cppblog.com/dbkong/archive/2006/12/09/16169.html

Thursday, 13 April 2017

Thursday, 16 February 2017

State Machines with C


Thank you very much to John Santic who gave a complete example of FSM in C:

One common way of conquering difficult software design problems is to use a state machine. First you figure out all the states the software can be in. Then you determine all the inputs to the state machine—all the events that can cause the state machine to take some action or to change states. Finally you determine the state machine outputs—all the actions that the state machine can perform.
When your state machine design is done, you'll have a list of states, a list of events (inputs), and a set of action procedures for each state that describe what the state machine does for each event (outputs).
There are two ways to code a state machine in C. One way uses a set of nested switch statements. The outer switch has a case for each possible state. Each of these outer cases has an inner switch with a case for each possible event. The actual code that gets selected performs the actions for that state/event. Alternately, the outer switch could have a case for each event, and the inner switch could have a case for each state.
Another more concise way of coding is to use a lookup table. First, number all your states consecutively, starting with 0—an enum is a convenient way to do this. Do the same for your events. Then make up a set of tables, one table per state. Each table has one entry per event, in the same order as the event enum. Then the entire set of tables is arranged in the same order as the state enum. Each item in a table is the function to execute to perform the action for that particular event in that particular state.
The listing below is an example with three states and two events, and therefore six action procedures.
/* Define the states and events. If your state machine program has multiple
source files, you would probably want to put these definitions in an "include"
file and #include it in each source file. This is because the action
procedures need to update current_state, and so need access to the state
definitions. */

enum states { STATE_1, STATE_2, STATE_3, MAX_STATES } current_state;
enum events { EVENT_1, EVENT_2, MAX_EVENTS } new_event;

/* Provide the fuction prototypes for each action procedure. In a real
program, you might have a separate source file for the action procedures of 
each state. Then you could create a .h file for each of the source files, 
and put the function prototypes for the source file in the .h file. Instead 
of listing the prototypes here, you would just #include the .h files. */

void action_s1_e1 (void);
void action_s1_e2 (void);
void action_s2_e1 (void);
void action_s2_e2 (void);
void action_s3_e1 (void);
void action_s3_e2 (void);
enum events get_new_event (void);

/* Define the state/event lookup table. The state/event order must be the
same as the enum definitions. Also, the arrays must be completely filled - 
don't leave out any events/states. If a particular event should be ignored in 
a particular state, just call a "do-nothing" function. */

void (*const state_table [MAX_STATES][MAX_EVENTS]) (void) = {

    { action_s1_e1, action_s1_e2 }, /* procedures for state 1 */
    { action_s2_e1, action_s2_e2 }, /* procedures for state 2 */
    { action_s3_e1, action_s3_e2 }  /* procedures for state 3 */
};

/* This is the heart of the state machine - where you execute the proper 
action procedure based on the new event you have to process and your current 
state. It's important to make sure the new event and current state are 
valid, because unlike "switch" statements, the lookup table method has no 
"default" case to catch out-of-range values. With a lookup table, 
out-of-range values cause the program to crash! */

void main (void)
{
    new_event = get_new_event (); /* get the next event to process */

    if (((new_event >= 0) && (new_event < MAX_EVENTS))
    && ((current_state >= 0) && (current_state < MAX_STATES))) {

        state_table [current_state][new_event] (); /* call the action procedure */

    } else {

        /* invalid event/state - handle appropriately */
    }
}

/* In an action procedure, you do whatever processing is required for the
particular event in the particular state. Among other things, you might have
to set a new state. */

void action_s1_e1 (void)
{
    /* do some processing here */

    current_state = STATE_2; /* set new state, if necessary */
}

void action_s1_e2 (void) {}  /* other action procedures */
void action_s2_e1 (void) {}
void action_s2_e2 (void) {}
void action_s3_e1 (void) {}
void action_s3_e2 (void) {}

/* Return the next event to process - how this works depends on your
application. */

enum events get_new_event (void)
{
    return EVENT_1;
}

ref:
http://johnsantic.com/comp/state.html     !!!!!!!!!!!!!!!!!!
http://codeandlife.com/2013/10/06/tutorial-state-machines-with-c-callbacks/
https://gist.github.com/nmandery/1717405
http://c.biancheng.net/cpp/html/99.html

Saturday, 31 December 2016

Error: '…' does not name a type

Most solutions to this problem talk about the headers. But the first reference below mentioned something that inspire me and solved my problem --  circular inclusion. 

There are many references about it online but I like this one:
http://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies

The way to think about this is to "think like a compiler".
Imagine you are writing a compiler. And you see code like this.
// file: A.h
class A {
  B _b;
};

// file: B.h
class B {
  A _a;
};

// file main.cc
#include "A.h"
#include "B.h"
int main(...) {
  A a;
}
When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.
......you can read on.

ref:
http://stackoverflow.com/questions/3961103/error-does-not-name-a-type (inspired by this)
http://stackoverflow.com/questions/2133250/does-not-name-a-type-error
http://stackoverflow.com/questions/8470822/error-x-does-not-name-a-type

http://stackoverflow.com/questions/625799/resolve-header-include-circular-dependencies

Monday, 28 November 2016

Using a void* Parameter



ref:
http://www.cplusplus.com/forum/general/50934/
http://stackoverflow.com/questions/3200294/how-do-i-convert-from-void-back-to-int


Friday, 14 October 2016

[Important] static variable and static global variable


There might be a time, that you DID assigned some value to an static variable, but in a function somewhere else, the change cannot be detected. For example, I met this problem when using Software Timers (Particle) whose callback functions don't take any input parameters and return values. Therefore, global/static variables are the only way of communication to the callback functions.

Here is the reason:

(1) Global variables are stored in static region.(2*) Non-static global variable and static global variable are different where non-static global variable (just defined without keyword static) can be seen in all project source files while static global variable can only be seen in the source file where it is defined. 

So if I want some variables to be static and global, I should not put "static" in front of the definition otherwise functions in other source files cannot see it.

///////////////////////////////////////////////////////////////////////////////////////////////////////////

More, if coping with c++ objects...here are some tips.

(1) Dealing with Class/Object pointers:

First, variables declared as external must be defined. So you need to have
Logger *log;
in Logger.cpp. You can also initialize it there like this:
Logger *log = new Logger();
Second, you don't need any more declarations, that is you just need to include Logger.h, no need to declare another Logger variable in Foo.h, just use log from Logger.h.
(2) Dealing with objects

In .h file:
extern Timer _timerXXX;
extern Timer _timerYYY;
extern Timer _timerZZZ;

In .cpp file:
// give inputs to the constructors
Timer _timerXXX(x1, x2); 
Timer _timerYYY(y2, y2);
Timer _timerZZZ(z1, z2);

ref:
http://www.cnblogs.com/sideandside/archive/2007/03/29/692559.html
http://blog.csdn.net/ymangu666/article/details/22277673

ref more:
http://stackoverflow.com/questions/8362679/extern-pointer-initialization



Wednesday, 21 September 2016

How to use #if 0 ... #endif


#if 0
...
#endif

basically tells the compiler that there is no need to compile this part of codes.

Usage:
(1) There might be something needed LATER in the program but we don't yet know exactly how this part works. So just leave it there now without compiling it.

(2) When we want to comment a block of codes using /* ... */, but there are some other comments in this block using  /* ... */, the only option we have is use #if 0 to avoid the compilation of it.

(3) Testing and debugging

#if 0
{original program...}
#else{new program...}
#endif


if we need to change back to the original program, just change the 0 back to 1.

ref:
http://www.programmer-club.com.tw/ShowSameTitleN/c/29150.html