Il faut se souvenir que fondamentalement, on travaille avec des bits. Vous pouvez donc attribuer une valeur de -4 à un entier non signé, ce qui placera une série de bits dans cet emplacement mémoire. Ces bits peuvent être interprétés comme -4 dans certaines circonstances . L'une de ces circonstances est évidente : vous avez indiqué au compilateur/système que les bits de cet emplacement mémoire devaient être interprétés comme un nombre signé à deux compléments. Donc, si vous faites printf("%s",i) printf fait sa magie et convertit le nombre complémentaire à deux en une magnitude et un signe. L'amplitude sera de 4 et le signe sera négatif, il affiche donc '-4'.
Cependant, si vous indiquez au compilateur que les données de cet emplacement mémoire ne sont pas signées, alors les bits ne changent pas mais à la place leur interprétation fait. Ainsi, lorsque vous effectuez une addition, que vous stockez le résultat dans un emplacement mémoire de type entier non signé et que vous appelez ensuite printf sur le résultat, il ne prend pas la peine de chercher le signe car, par définition, il est toujours positif. Il calcule la magnitude et l'imprime. La magnitude sera fausse car l'information du signe est toujours encodée dans les bits, mais elle est traitée comme une information de magnitude.