How do I use variables in functions/procedures

Yes, at the end of the day, for a given LED you don’t need full 5-byte arrays when only one bit is set. You can make it more compact by using a struct that stores the shift register index (0–4) and the bit position (0–7) for each LED. Then your setLED function just sets or clears the bit in the shadow array. May be something like this (fully untested - typed here)

const byte dataPin = 11;
const byte clockPin = 12;
const byte latchPin = 8;

struct LED {
  byte reg;   // shift register index 0..4
  byte bit;   // bit position 0..7
};

// define LEDs by which register and which bit
const LED leds[] = {
  {0,0},{0,0},{0,0},{0,0},{0,0}, // placeholders 0–4
  {2,2}, {2,3}, {2,4}, {2,5}, {2,6},
  {2,7}, {4,0}, {4,1}, {4,2}, {4,3},
  {4,4}, {4,5}, {1,2}, {1,3}, {4,6},
  {4,7}, {3,0}, {3,1}, {1,4}, {1,5},
  {1,6}, {1,7}, {3,2}, {3,3}, {3,4},
  {3,5}, {0,0}, {0,1}, {0,2}, {0,3},
  {3,6}, {3,7}, {2,0}, {2,1}, {0,4},
  {0,5}
};

byte shadow[] = {0,0,0,0,0};

void setLED(int pinNumber, bool state) {
  LED l = leds[pinNumber];
  if(state) shadow[l.reg] |= (1 << l.bit);
  else shadow[l.reg] &= ~(1 << l.bit);

  digitalWrite(latchPin, LOW);
  for(int i = 0; i < 5; i++) shiftOut(dataPin, clockPin, MSBFIRST, shadow[i]);
  digitalWrite(latchPin, HIGH);
}

void setup() {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
}

void loop() {
  setLED(5, HIGH);
  delay(500);
  setLED(5, LOW);
  delay(500);
}