Die Formatzeichen haben folgenden Aufbau:
%[Parameter][Bitschalter][Breite][.Genauigkeit][Länge]Typ.
Der Typ d gibt an, dass eine ganze Zahl (das heißt eine Zahl aus ℤ) in Dezimaldarstellung ausgegeben werden soll.
Die Länge hh gibt an, dass der auszugebende Wert aus einem signed char kommt.
Zusammengefasst besagt %hhd: ein signed char wird als ganze Zahl ausgegeben.
Auf die gleiche Weise werden die Längenangaben h, l und ll verwendet für die Ausgabe von short, long bzw. long long.
Mit Ausgabe in hexadezimaler Darstellung hat das nichts zu tun. Dafür gibt es den Typ x. Zum Beispiel wird mit %lx ein unsigned long int in hexadezimaler Darstellung ausgegeben.
Weitere Einzelheiten findest du im Artikel printf format string aus Wikipedia.