1 . Objective-C Programming: Will Learning C and/or Smalltalk Help? [closed]

Answer :

Smalltalk is an incredibly compact language and remains one of the most pure object oriented languages. Objective-C is a pragmatic compromise between Smalltalk and C, which makes for some very substantial differences. For example, in Smalltalk everything is an object — even simple numbers — and every manipulation of an object is by message sending. Messages are evaluated in the same order irrespective of their name. So e.g. the following:

8 + 9 / 23 + 16 * 8

Is evaluated in strict left-to-right order because the operators '+', '/' and '*' have no special meaning to the language being just messages that are passed on to number objects.

Objective-C adds Smalltalk-style objects to C but is also a strict superset of C that retains C's primitive types and built-in operators. So in Objective-C the normal mathematical order of operations would be applied to the expression above — the division and the multiplication would be done first, the additions afterwards.

Learning C is absolutely essential to a thorough understanding of Objective-C. Objective-C is a strict superset of C and explicitly uses exactly the same syntax and semantics as far as they go. It grafts the concept of objects onto C by virtue of C's ability to retain a pointer to a thing without knowing how to apply any operations to the thing. It then extends the C syntax to provide a means for posting messages to objects and for declaring and implementing the messages an object may receive.

A lot of the general design of the Objective-C runtime, especially when coupled with Cocoa, comes directly from Smalltalk, including the concept of a selector, the use of metaclasses as factories for instances of classes, the hierarchy and system of inheritance, the division of model-view-controller (a Smalltalk original, albeit now almost ubiquitous) and a lot of the messages defined on the standard collections and objects.

Off the top of my head, Smalltalk also differs greatly in its system of flow control and has a similar but subtly different idea of a 'block' (though most newer implementations have brought the two into line). Apple have actually implemented blocks as an extension at the C level which is utilised by a lot of the newer methods on Objective-C objects.

That all being said, the Goldberg Smalltalk-80 book is extremely well written, easy to read and the language is so simple that you can learn the whole language in just two or three chapters. Most of the complexity is swallowed by the objects available in the runtime, and obviously that stuff doesn't transfer. The benefit to you is that the ideological stuff about objects and runtimes ends up very separated from the specifics in print. Conversely, C makes stuff like flow control and arithmetic a language feature, which means more syntax and more to read before you really feel you know what's going on.

So, in conclusion: the Smalltalk-80 book (the purple one) is definitely worth a read and extremely helpful but not necessarily entirely relevant. Learning C is essential in any case; my references to K&R are for comparison.

Leave a Comment

1 . PL/SQL Macro, like in C Programming?

Answer :

Just following on from OldProgrammer's comments, I think you would want a single function that uses dynamic SQL to return single values from very similar SQL statements.

Below is an example of how this can be acheived:


  function get_field_val(
      p_field          varchar2,
      p_table          varchar2,
      p_where_clause   varchar2
  )   return varchar2 is
      v_query     clob;
      v_result    varchar2(4000);

      v_query := 'select to_char(' || p_field ||')' ||
                 'from ' || p_table || ' ' || p_where_clause;                 

      execute immediate v_query into v_result;

      return v_result;



          p_field        => 'COLUMN_NAME',
          p_table        => 'ALL_TAB_COLUMNS',
          p_where_clause => 'where owner = ''SYS'' and table_name = ''ACCESS$''
              and column_id = 1'));

          p_field        => 'max(table_name)',
          p_table        => 'all_tables',
          p_where_clause => 'where owner = ''SYS'''));


A few things to note about this:

  1. This function can only return a single varchar value. If you want different types or arrays of values you'll need to approach this using built-in or user defined plsql collections.
  2. It's probably a bad idea to make this kind of function public as it means anyone could run any query with the same privledges as the package definer (unless you create it with AUTHID CURRENT_USER)

2 . Simple C programming gui?

Answer :

You're looking for a good book on Win32 API programming using C. And you're in luck, there's a great book that pretty much everyone uses to learn it. It's written by Charles Petzold, and it's called (aptly enough) Programming Windows. You want the 5th edition, which is the most recent version that discusses Win32 programming.

There are also various tutorials available online if you search for "Win32 programming". However, a number of them contain some errors and misunderstandings (like the difference between ANSI and Unicode strings), and the good ones are rather short and incomplete. You won't learn everything you need to know to write a non-trivial program from online tutorials, but you should be able to get something really simple up on the screen. This one by theForger is one I've seen recommended many times.

Be warned, though, that writing GUI code (especially at such a low level) tends to be a lot more verbose than simply getting text onto the screen for a console program. You're going to end up writing a bunch of code that is used only to make the GUI work and has nothing to do with the logic of your program. It's much easier if you learn the C language first, and that's best done through simple console-type, text-only programs.

As for your specific question, you've created three textbox controls on the screen, named hwnd_TextBoxX, where X is a number between 1 and 3. As you probably already know, hwndindicates a handle to a window (wnd), and so those variables hold handles to the textbox windows.

The Win32 API provides a GetWindowText function, which you can use to retrieve the text from a particular window. You pass it a handle to the desired window (hWnd), a pointer to a character buffer, and an integer value indicating the length of your buffer. Already, the ugly nature of the C language crops up—you have to understand how strings work in C in order to call the function correctly.

Once you've retrieved the string displayed in one of the textboxes, you can display it in another textbox window using the similar SetWindowText function, which takes only the window handle (hWnd) and a pointer to the buffer containing the string.

The code would look something like this:

// Get the text displayed in textbox 1
TCHAR szBuffer[100];
GetWindowText(hwnd_TextBox1, szBuffer, 100);

// Display that text in textbox 3
SetWindowText(hwnd_TextBox3, szBuffer);

To do this in response to a click on a button, you'll need to learn about the Win32 equivalent of "events"—window messages. Child windows, like button controls, send notification messages to their parent window (i.e., a dialog) when something potentially interesting happens, like the user clicks on them.

In particular, a button control sends its parent a through the WM_COMMANDmessage. By handling the WM_COMMAND message in your main window's window procedure (WndProc) method, you can check that the lParam parameter matches your button control's window handle (hWnd) and that the HIWORD(wParam) matches the BN_CLICKED notification code.

You definitely need a good book that contains step-by-step sample code for that one. It's a bit too difficult to explain thoroughly in a Stack Overflow answer.

3 . Confused on “zombie processes” in c programming?

Answer :

A zombie process is a child process that terminates, but has not been waited for by the parent. Child processes are typically created by fork:

int pid = fork();
if (pid < 0) {
     // fork failed
} else if (pid == 0) {
    // this is the child process
// this is the parent

fork returns 0 to the child process and a positive pid to the parent. There are two cases in terms of their termination:

  1. child exit before parent, then the child becomes a "zombie" process until the parent calls the wait family functions to get the child's exit status.

  2. parent exit before child, then the child will be re-parented to the init process, the init process will call wait upon the child exits. This works because the parent will receive SIGCHLD signal when its child exits, and it can call wait in the signal handler. So in this case, no zombie will be created.

Also, note the posix defines no zombies are created if the SIGCHLD is ignored by the parent:

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD. (The original POSIX standard left the behavior of setting SIGCHLD to SIG_IGN unspecified. Note that even though the default disposition of SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results in different treatment of zombie process children.)

For the two case in the OP:

// Case 1
while(fork())  // same as while(fork() != 0)


// Case 2
while(!fork()) // same as while(fork() == 0)


The 1st code keeps forking in the parent, no matter it succeeds or not, and the resulted children will exit immediately since the return value will be 0. Since the parent is hung in the while loop no matter the fork succeeds or failed(fork only returns 0 for children), all the children will become zombie.

For the 2nd case, the parent exit immediately when fork returns, but the child will keep forking, and this child will again do the same, that is, it will exit immediately, and the child it created will keep forking. In this case, since the parent exit, all its children will reparented to init process, as a result, no zombies will be created.

4 . xcode compile console application - c programming?

Answer :

If you use the boiler plate template for a cocoa application, which uses NSApplicationMain and the few other structures necessary to jumpstart a cocoa program, then you are free to start writing C methods without ever hitting objective-c. Caveats:

1) for testing purposes it looks like, when using xcode, your best bet is to start with the "Window-Based Application" template offered under the iphone category of new projects. It is a minimal template with no UI -- just a window.

2) There is no "main()" persay in an iphone. You have to place your code in the "AppDelegate.m" file which will actually be "[YourProjectName]AppDelegate.m". Inside here you will find a method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

    return YES;

This is a good place to call C functions you've written, which you can do either in that source file, or better, in a separate file that you #import. Note that the application will block until all of your c-code finishes executing.

3) There is no printf, i don't believe. Sorry. One way to get info out is to use NSLog -- but that expects objective-c strings not C strings. So if you want to actually see any status out of your C program, you'll have to use just a tiny bit of objective-c. The line in question is:

char *your_char_pointer = //...gimme a string;
NSLog([NSString stringWithCString:your_char_pointer]);

where this will convert your C String into an Objective-C string that NSLog will happily print to the console (seen by using the console application in the Utility folder in Applications on OSX).

5 . “The C programming language” book exercise 1.2 possible wrong result?

Answer :

Indeed, on the first time through the while loop, fahr has the value 0, and that is what will be printed. This is probably a typo in your edition of the book: we have multiple reports in the comments that other editions have 0 where yours has 1.

You are right to be concerned about old C code behaving differently with newer compilers. However, this program does not have any of the things in it that usually cause problems with newer compilers: no pointer aliasing, no concurrency, no arithmetic overflow, etc. The computation of the first two values of the celsius column does involve integer division with a negative dividend, which was partially implementation-defined prior to C1999; if the book had given -18 and -7 for those values, that would have been why. And modern compilers will issue a warning about the missing return type of main, but that doesn't affect the semantics of the program. (I'm not aware of any modern C compiler that actually issues an error for "implicit int", either in its default mode or in its "strictly conforming to C2011" mode. There's usually a way to tell it to make that particular warning into an error, of course.) None of these issues could have have caused the first value of fahr to be printed as 1.

Please learn from this that you should trust your ability to mentally simulate the execution of a program a little more, but printed books a little less. You would also be well-advised to get a newer C textbook—not just a newer edition of K&R, but an entirely new book, that covers the modern language. I regret to say I don't have any recommendations, though.

6 . C Programming Optimization and Processor Extensions?

Answer :

The idea is to have per CPU optimized libraries (SSE, AVX etc), and call something like _may_i_use_cpu_feature() to dynamically determine what feature is available at runtime and load the "best" implementation for the CPU.

For portable code you want to use sqrt() - and some runtime libraries have optimized implementation that are good enough. If you want full control and maximize performance on a specific platform, and don't care about portability, you can write hand optimized assembly (or use intrinsics).

Most performance is gained by better algorithms anyways...

7 . How can i better understand the kernel c programming code?

Answer :

Take a look a the book Linux Device Drivers by Corbet et al. Yeah, it looks like it's not what you asked for but, really, you can't write a device driver without understanding the kernel and being able to write a device driver is about as far as most people should go. Also, keep in mind that while it is a monolithic kernel it is "modular". What you have in your question above is mostly part of the filesystem stuff which can be understood, more or less, on its own -- as can other subsystems.

For the core kernel which holds all of these together look at the Kernel Book. It also has links to other sources. There is another book, though very dated, by Remy Card about the kernel (pre 2.2 kernel). From the amazon.com for that book you can see related titles.

If you really want to begin correctly do it with something small and understandable. Take a look at MINIX and the accompanying textbook (Torvalds may have learned something about OS fundamentals from this very book).

8 . What is the comparison algorithm used in “strcmp” - C programming?

Answer :

The GNU implementation of the standard C library, glibc, is open source and you can just read strcmp.c if you are curious. There is not much to it. Here it is:

/* Compare S1 and S2, returning less than, equal to or
   greater than zero if S1 is lexicographically less than,
   equal to or greater than S2.  */
int strcmp (const char *p1, const char *p2)
  register const unsigned char *s1 = (const unsigned char *) p1;
  register const unsigned char *s2 = (const unsigned char *) p2;
  unsigned reg_char c1, c2;

      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0')
        return c1 - c2;
  while (c1 == c2);

  return c1 - c2;

9 . UML for C programming language?

Answer :

I don't know of any existing resources that discuss using UML specifically for C. As others have mentioned, UML is language-agnostic.

Keep in mind that with UML, you can have a model for the problem domain, and another for the implementation. Try not to model the problem domain in terms of C, but rather as high-level OO. Once you understand the problem domain adequately enough, you can begin modeling an implementation.

For modeling procedural-style C implementations, the following diagrams could be useful:

  • Class diagram:
    • Show C module APIs
    • Show C module relationships (mostly dependencies for non-OO)
    • Show structures and enumerations (using < < stereotype> >)
  • Package diagram: Show contents (modules) of libraries, and the dependency relationships between libraries
  • Activity diagram: Flowcharting non-trivial algorithms
  • Sequence/collaboration diagram: Show how events/messages between modules/entities/inputs/outputs occur in time
  • Statechart diagram: For state machines, of course!

Expanding on class diagrams, you can "abuse" them in the following way for procedural-style C:

  • Global extern functions -> public methods
  • Local static functions -> private methods
  • Global extern variables -> public members
  • Local static variables -> private members
  • Structs -> class with "struct" stereotype
  • #define constants -> class with "enumeration" stereotype

Experiment, and you'll find your own conventions for abusing UML.

10 . What is the significance of forward declaration in C programming?

Answer :

Forward declarations of functions in C typically have two different uses.


The header of exported functions are declared in a header file which is included in a client module.

Mutual Recursion

In mutual recursion two functions call each other repeatedly. Without a forward declaration one of the two functions will be undeclared in the body of the other.


int Odd(int n);

int Even(int n)
    return (n == 0)? 1: Odd(n - 1);

int Odd(int n)
    return (n == 0)? 0: Even(n - 1);

With a function pointer though, we can do without a forward declaration:

int (*odd)(int n);

int Even(int n)
    return (n == 0)? 1: odd(n - 1);

int Odd(int n)
    return (n == 0)? 0: Even(n - 1);

void Init(void)
    odd = Odd;

11 . C Programming - Sum of 2D arrays?

Answer :

The first parameter is adjusted to

int ( *array )[SIZE]

that is it is a pointer.

So the expression array + count also has the type int ( * )[SIZE]. To get the corresponding "row" of the array you have to dereference the pointer

*( array + count )

In this case you will have an object of the type int[SIZE] that in turn in the expression

*( array + count ) + count

is implicitly convered to the type int *.

Now dereferencing the whole expression you will get the target element

*( *( array + count ) + count )

It is better to declare the function as having the parameter of the variable length array.

Here is a demonstration program

#include <stdio.h>

void diagonals2D( long long int *sum, size_t n, int a[n][n] )
    *sum = 0;

    for ( size_t i = 0; i < n; i++ )
        *sum += *( *( a + i ) + i );

#define N   3

int main(void) 
    int a[][N] =
        { 10, 20, 30 },
        { 10, 20, 30 },
        { 10, 20, 30 }      

    long long int sum;

    diagonals2D( &sum, N, a );

    printf( "sum = %lld\n", sum );

    return 0;

Its output is

sum = 60

12 . Safe C programming?

Answer :

The C language defines the behavior of certain programs as "undefined". They can do anything. We'll call such programs erroneous.

One of them is a program that accesses outside the declared/allocated bounds of an array, which your program very carefully does.

You program is erroneous; the thing your erroneous program happens to do is what you see :-} It could "overwrite the OS"; as a practical matter, most modern OSes prevent you from doing that, but you can overwrite critical values in your process space, and your process could crash, die or hang.

The simple response is, "don't write erroneous programs". Then the behavior you see will make "C" sense.

In this particular case, with your particular compiler, the array indexing "sort of" works: you index outside the array and it picks up some value. The space allocated to m is in the stack frame; m[0] is at some location in the stack frame and so is "m[-1]" based on machine arithmetic combining the array address and the index, so a segfault does not occur and a memory location is accessed. This lets the compiled program read and write that memory location ... as an erroneous program. Basically, compiled C programs don't check to see if your array access is out of bounds.

Our CheckPointer tool when applied to this program will tell you the array index is illegal at execution time. So, you can either eyeball the program yourself to see if you've made a mistake, or let CheckPointer tell you when you make a mistake. I strongly suggest you do the eyeballing in any case.

13 . Using “make” C Programming (Learn C the Hard Way)?

Answer :

Both work; they just do different tasks.

  • make ex1.c says "using the rules in the makefile plus built-in knowledge, ensure that the file ex1.c is up to date".

    The make program finds ex1.c and has no rules to build it from something else (no RCS or SCCS source code, for example), so it report 'Nothing to be done'.

  • make ex1 says "using the rules in the makefile plus built-in knowledge, ensure that the file ex1is up to date".

    The make program finds that it knows a way to create an executable ex1 from the source file ex1.c, so it ensures that the source file ex1.c is up to date (it exists, so it is up to date), and then makes sure the ex1 is up to date too (which means 'file ex1 was modified more recently than ex1.c). If you've edited ex1.c since you last ran make, it will do the compilation to make ex1 newer than ex1.c. If the compilation fails, the file ex1 won't exist, so you'll get another recompilation next time too. And once it is up to date, then make won't rebuild ex1 again until you modify the source again.

This is the way make is designed to work.

14 . Very huge matrix in C programming?

Answer :

For a matrix as large as that, I would try to avoid all those calls to malloc. This will reduce the time to set up the datastructure and remove the memory overhead with dynamic memory (malloc stores additional information as to the size of the chunk)

Just use malloc once - i.e:

#include <stdlib.h>
int *matrix = malloc(R * P * sizeof(int));

Then to compute the index as

index = column + row * P;

Also access the memory sequentially i.e. by column first. Better performance for the cache.

15 . Emacs as a C Programming IDE Configuration?

Answer :

It's been a while since I've done C but here are a few pointers.

  1. Use flymake for on the fly error analysis. I have used it for Python and C and it's really awesome.
  2. Syntax highlighting is there by default in the C mode.
  3. M-x compile is geared towards make so if you have a Makefile in your setup, it should work fine (the defauly flymake rules use this as well). A rule like this


          gcc -Wall -o nul -S ${CHK_SOURCES}

    would take care of flymake. This is useful when you edit in subdirectories but want to compile fromt he top.

  4. etags is useful to jump around the code. GnuGlobal also seems to be popular.
  5. Can't comment on ECB since I've never really gotten it to work completely and when I sort of did, I never found it that useful. I use autocomplete.el to do completions but it's not context sensitive.
  6. There is no suggestion 6.
  7. The inbuilt vc integration is not so hot for git and so I use magit instead. There should be similar issues with mercurial.
  8. There are some notes here on setting up your indentation.
  9. You should use which function mode. It's saved me a lot of headache in the past.
  10. The defaults for GUD are pretty decent but you should take a while and familiarise yourself with them to use it's power completely.
  11. I heavily use org-capture to move TBDs into my org mode buffers so that I can track them as TODO items. This is for all languages. I also use org-mode to maintain a development diary for all my projects.