It seems that C has its own quasi-objects such as 'structs' that can be considered as objects
Let's together you and I read through the Wikipedia page on object oriented programming and check off the features of C-style structs that correspond to what is traditionally considered to be object-oriented style:
(OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions
Do C structs consist of fields and methods together with their interactions? No.
Programming techniques may include features such as data abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance.
Do C structs do any of these things in a "first class" way? No. The language works against you every step of the way.
the object-oriented approach encourages the programmer to place data where it is not directly accessible by the rest of the program
Do C structs do this? No.
An object-oriented program will usually contain different types of objects, each type corresponding to a particular kind of complex data to be managed or perhaps to a real-world object or concept
Do C structs do this? Yes.
Objects can be thought of as wrapping their data within a set of functions designed to ensure that the data are used appropriately
each object is capable of receiving messages, processing data, and sending messages to other objects
Can a struct itself send and receive messages? No. Can it process data? No.
OOP data structures tend to "carry their own operators around with them"
Does this happen in C? No.
Dynamic dispatch ... Encapsulation ... Subtype polymorphism ... Object inheritance ...
Open recursion ... Classes of objects ... Instances of classes ... Methods which act on the attached objects ... Message passing ... Abstraction
Are any of these features of C structs? No.
Precisely which characteristics of structs do you think are "object oriented"? Because I can't find any other than the fact that structs define types.
Now, of course you can make structs that have fields that are pointers to functions. You can make structs have fields that are pointers to arrays of function pointers, corresponding to virtual method tables. And so on. You can of course emulate C++ in C. But that is a very non-idiomatic way to program in C; you'd be better off just using C++.
And also, C files themselves are basically separate "modules", right? Then aren't modules kind of like 'objects' too?
Again, what characteristics of modules are you thinking of that makes them act like objects? Do modules support abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance?
Abstraction and encapsulation are pretty weak. Obviously modules are modular; that's why they're called modules. Messaging? Only in the sense that a method call is a message and modules can contain methods. Polymorphism? Nope. Inheritance? Nope. Modules are pretty weak candidates for "objects".