With return statements in each if branch.
In your code, you have return statements in each of the if conditions. When you have a situation like this, there are two ways to write this. The first is how you've written it in Example 1:
if (a == b1) {
   return c1;
} else if (a == b2) {
   return c2;
} else {
   return c11;
}
The other is as follows:
if (a == b1) {
   return c1;
}
if (a == b2) {
   return c2;
}
return c11; // no if or else around this return statement
These two ways of writing your code are identical.
The way you wrote your code in example 2 wouldn't compile in C++ or Java (and would be undefined behavior in C), because the compiler doesn't know that you've covered all possible values of a so it thinks there's a code path through the function that can get you to the end of the function without returning a return value.
if (a == b1) {
   return c1;
}
if (a == b2) {
   return c2;
}
...
if (a == b11) {
   return c11;
}
// what if you set a to some value c12?
Without return statements in each if branch.
Without return statements in each if branch, your code would be functionally identical only if the following statements are true:
- You don't mutate the value of ain any of theifbranches.
- ==is an equivalence relation (in the mathematical sense) and none of the- b1thru- b11are in the same equivalence class.
- ==doesn't have any side effects.
To clarify further about point #2 (and also point #3): 
- ==is always an equivalence relation in C or Java and never has side effects.
- In languages that let you override the ==operator, such as C++, Ruby, or Scala, the overridden==operator may not be an equivalence relation, and it may have side effects. We certainly hope that whoever overrides the==operator was sane enough to write an equivalence relation that doesn't have side effects, but there's no guarantee.
- In JavaScript and certain other programming languages with loose type conversion rules, there are cases built into the language where ==is not transitive, or not symmetric. (In Javascript,===is an equivalence relation.)
In terms of performance, example #1 is guaranteed not to perform any comparisons after the one that matches. It may be possible for the compiler to optimize #2 to skip the extra comparisons, but it's unlikely. In the following example, it probably can't, and if the strings are long, the extra comparisons aren't cheap.
if (strcmp(str, "b1") == 0) {
  ...
}
if (strcmp(str, "b2") == 0) {
  ...
}
if (strcmp(str, "b3") == 0) {
  ...
}