I was wondering why the txn_count field in a block exists. The count of transactions could be determined by parsing the txns field in tx format, right?
Yes, it could, but it isn’t. Ultimately serialization formats are a convention, and Satoshi picked one when he created the initial software which has persisted in the protocol. It could be changed, but why bother?
The tx_in and tx_out can be just parsed and the count can be determined based on that, right?
That’s not quite true – you need some way of conveying at least where the inputs end and the outputs begin (which in the existing protocol is served by the txin count). When deserializing a list of transactions (like in a
block message), you also need to know where each transaction ends and the next one begins (which in the existing protocol is served by the txout count).
Is it also used so you can reserve a certain amount of memory before parsing the transactions you think?
You could, but that actually isn’t done (at least in Bitcoin Core). The problem is what if you receive a block that claims to contain a billion transactions? Instead, it will allocate buffer space in increments of at most a few MB, so an attacker would need to actually send megabytes of data to get you to allocate that much.