Thread: Object-oriented programming using C

  1. #1
    Registered User
    Join Date
    Sep 2018
    Posts
    51

    Question Object-oriented programming using C

    Hi, guys!
    I read that there are many problems with code editing in large C programs. How to avoid it? Could I use OOP in C and how? Thank you.

  2. #2
    Registered User
    Join Date
    Sep 2020
    Posts
    150
    You can do some form of OO in C.
    Object-Oriented Programming (OOP) in C | Codementor

    I read that there are many problems with code editing in large C programs
    What kind of problems ?
    Is there a reason why you don't want to move on to C++ ?

  3. #3
    Registered User
    Join Date
    Dec 2011
    Location
    Namib desert
    Posts
    94
    Many large programs are programmed in plain C !

  4. #4
    Registered User
    Join Date
    Oct 2021
    Posts
    138
    Quote Originally Posted by Wido View Post
    Hi, guys!
    I read that there are many problems with code editing in large C programs. How to avoid it? Could I use OOP in C and how? Thank you.

    Hi! Ok so C is NOT an OOP language. C only supports the basic structure (called "struct"). This means only members for your struct and that's pretty much it. Below I will show you some examples and I suppose that you are familiar with OOP and the terms I'm going to use. I also suppose that you are familiar with pointers, if not then learn about them first will probably be a good idea. You can come back to this post later. Let's see:

    Code:
    #include <stdio.h> // This is expected and I will not include it in the next code snippets to save space
    
    struct Human {
       const char* name; // Member "name".  Semicolon after the end of any member
       int age, height; // Just like variable, comma will create a lot of members of the same type
    }; // Notice how we need to have a semicolon here
    
    int main() {
      struct Human maria = { "Maria", 19, 158 };
      // Notice how we need to use the "struct" keyword to tell the compiler that we want to create a custom type that is a struct
      // The curly brackets will initialize the members in order to the given value. If you don't give a value to a member, it will
      // get the default value for its type. You could also change the order you initialize use dot syntax. Consider the following object
      struct Human john = { .age = 19, .name = "John, .height = 195 };
      return 0;
    }
    Now to use the members we use a dot after the name of the object. If you use a pointer to an object, you have to dereference the pointer or you can use the arrow operator (->) that does this automatically for you. Example:

    Code:
    // Human struct expected here
    
    void print_human(struct Human* h) {
      printf("name = %s\nage = %d\nheight = %d\n",
          (*h).name, // dereference the pointer
          h->age, // use the arrow operator to do it automatically
          h->height );
    }
    
    int main() {
      struct Human maria = { "Maria", 19, 158 };
      // Use the "name" member from the "maria" Human object
      printf("maria's name is: %s\n", maria.name);
      print_human(&maria);
      return 0;
    }
    And normally that's pretty much it about where C structs stop. Or maybe not????? It's your lucky day because I'm here to the rescue!!! So there are some more things you can "fake" to make it act like OOP languages but there is a limit you can't pass. Let's see

    Methods. You can use function pointers to "fake" methods. But it is bad, you will have to pass "this" manually. Let's see:

    Code:
    struct Human {
      const char* name;
      int age;
      // This is a function pointer called "print" and it is a
      // pointer to a function that takes a Human type object
      void(*print)(struct Human* h);
    };
    
    void print_human(struct Human* h) {
      printf("name = %s\nage = %d\n", (*h).name, h->age);
    }
    
    int main() {
      // The "print" function pointer member points to the "print_human" function
      struct Human maria = { "Maria", 19, print_human };
      // Use it and pass "maria" as the member (which would be the equivalent of "this"/"self" and C++/D/Java/Python etc.
      maria.print(&maria);
    }
    You can also "fake" polymorphism using pointers. Let's see:

    Code:
    #include <string.h>
    
    struct student {
      const char* name;
      int age;
    };
    
    // This is like "fake" manual inheritance
    // BE CAREFUL!!! The common members
    // must be first in the same order for each
    // type. You can change the name of the members
    // but the type must be the same. In this case,
    // the first member must be of type "char*" and the
    // second member must be of type "int". Let's see
    struct teacher {
      const char* name;
      int age;
      int teacher_id;
    };
    
    void print_basic(struct student* s) {
      printf("name = %s\nage = %d\n\n", s->name, s->age);
    }
    
    // A void pointer accepts anything! Use "type" to tell the
    // function which type to cast the pointer to
    void print_type(const char* type, void* o) {
      if (strcmp(type, "s") == 0) {
        // Cast the value to a "student*" type object. Now do whatever you want
        struct student* st = (struct student*)o;
        printf("Student { \"%s\", %d }\n", st->name, st->age);
      }
     
      else if (strcmp(type, "t") == 0) {
        // Cast the value to a "teacher*" type object. Now do whatever you want
        struct teacher* tc = (struct teacher*)o;
        printf("Teacher { \"%s\", %d, %d }\n", tc->name, tc->age, tc->teacher_id);
      }
    }
    
    int main() {
      struct student mike = { "Mike", 20 };
      struct teacher anna = { "Anna", 35, 1028 };
      // "print_basic" normally takes a "student" pointer but it
      // it can take any pointer and it will automatically cast it to
      // to a "student" pointer. It is YOUR responsibility to make
      // sure that this type will have the data and will be able to
      // be used as a "student". Now "teacher" is guarented to be
      // able to do that because the first two members of "teacher"
      // are the same type of the same two members of "student"
      // You will even get a warning for "incopatible pointer type"
      print_basic(&anna);
      // "print_type" can take any pointer and it will cast it to the
      // type that we will tell it with the value that we will pass to
      // the "type" variable. Still it is your responsibility to know
      // what you are doing here
      print_type("s", &mike);
      print_type("t", &anna);
    }
    You can make things a little bit more easier to use using the "_Gereric" from C11 but I don't want to make your mind explode with so much continues knowledge so I will let you explore it yourself when you feel like doing Also you can use "typedef" to not have to type "struct" every time you want to use a custom struct type. Happy coding!
    Last edited by rempas; 12-27-2021 at 05:23 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 09-07-2017, 11:35 AM
  2. What is Object Oriented Programming?
    By sunrising in forum C++ Programming
    Replies: 6
    Last Post: 04-23-2008, 07:58 AM
  3. Object Oriented Programming
    By obaid in forum C++ Programming
    Replies: 5
    Last Post: 08-22-2007, 05:31 AM
  4. Object Oriented Programming
    By eric123 in forum C++ Programming
    Replies: 6
    Last Post: 11-30-2005, 04:56 AM
  5. C++ and Object Oriented Programming
    By Visual Develope in forum C++ Programming
    Replies: 3
    Last Post: 05-05-2002, 05:27 AM

Tags for this Thread