If the compiler lets you to access the pins with PINA.0 then the PINA might be a bitfield. Bitfields does not have addresses.
With this statement: char a[3]={PINA.0,PINB.2,PORTC.4};
you are storing pin values in the array. So, later when you write a[2]=1
you write 1 to the copied register value, not to the actual register. If you want to have right results you should work directly with the registers, or macros.
//setting PINA.2 = 1
PINA |= 1<< 2;
you can also define a macro like
#define SET_BIT(PORT_NR,BIT) (PORT_NR |= (1<<BIT))
#define CLEAR_BIT(PORT_NR,BIT) (PORT_NR &= ~(1<<BIT))
and call it:
SET_BIT(PINA,2);
CLEAR_BIT(PINA,2);
However , if you still want to keep them into an array you might be able to store pointer to functions in the array and then call them.
void setBit(struct port_operation* a,unsigned char bit){
return a->_port |= (1<<bit);
}
void clearBit(struct port_operation* a,unsigned char bit){
return a->_port &= ~(1<<bit);
}
typedef struct _port_operation{
unsigned char _port;
void(*set)(struct _port_operation* ,unsigned char);
void(*clear)(struct _port_operation* ,unsigned char);
}port_operation;
port_operation port_op_a;
port_op_a._port = PORTA;
port_op_a.set = setBit;
port_op_a.clear = clearBit;
port_operation port_op_b = port_op_a;
port_op_b._port = PORTB;
port_operation[2] = {port_op_a,port_op_b};
//set 1 to PORTA bit 1
port_operation[0].set(port_operation[0],1);