PORTS are addresses to memory mapped registers, they are defined as: volatile uint8_t *
Check the following code (use at own risk) it gives some idea how it works under the hood.
void setup()
{
Serial.begin(115200);
Serial.println("\nprint addresses or well known ports\n");
Serial.println((int)(&PINB), HEX);
Serial.println((int)(&DDRB), HEX);
Serial.println((int)(&PORTB), HEX);
Serial.println((int)(&PINC), HEX);
Serial.println((int)(&DDRC), HEX);
Serial.println((int)(&PORTC), HEX);
Serial.println((int)(&PIND), HEX);
Serial.println((int)(&DDRD), HEX);
Serial.println((int)(&PORTD), HEX);
Serial.println("\nuse a variable for a well known port\n");
volatile uint8_t * myport = &DDRC;
Serial.println((int)(&DDRC), HEX);
Serial.println((int) myport, HEX);
Serial.println(DDRC, HEX);
Serial.println(*myport, HEX);
*myport = 0x0A; // write 0x0A to address of DDRC
Serial.println(DDRC, HEX); // check
Serial.println(*myport, HEX); // double check
}
void loop()
{
}
so you can use myport to point to one of the "hard coded ports"