If we neglect all advanced object oriented programming concepts, as inheritance or polymorphism by type parameters everything boils down to the same thing.
In C++ you have objects and you call methods that are attached to them, in C you have structs and you call global functions by passing these functions by argument.
What I mean is that the essential oop paradigm is conceptually to have objects which are able to perform things through their methods. Now in C you can obtain the same behavior but you have functions which are not attached to any object.
So basically in C++ or Java you would have:
class Point {
private:
int x, y;
public:
Point(int x, int y) : x(x), y(y) { }
void draw() { ... }
};
In pure C you would have:
struct Point {
int x, y;
}
struct Point makePoint(int x int y) {
struct Point p = {.x = x, .y = y};
return p;
}
void drawPoint(struct Point p) {
..
}
But the semantic power of both representation is essentially the same, the syntax is different though (and even the concept behind it). Of course everything changes if we start considering more powerful oop features.
In many circumstances you don't need all this power to represent objects, not everything is meant to be oop neither all problems are best solved with an oop approach. If writing a complex engine for a game in C would be overkill at the same time writing low level functions in Java which operates with the system would be overkill at the same time.