ちなみに俺は、少しでも複雑だと感じたら、一時変数を使う場合が多い。
例えばこの場合だと(あまり複雑ではないが)
if (get_n...) {
 char *s = ary[get_n - 1];
 printf(..., s);
}
もし何らかの勘違いミスがあっても
コンパイラのエラーメッセージが代入の行を示してくれるのでわかりやすい。
この場合に char *s = *ary[..]; だと、コンパイラが意味のあるエラーメッセージを出してくれるはず。
まあループの中などでレジスタ割付に期待する面も無くはないが
その辺はコンパイラの最適化がやってくれる場合もある。

もちろん、一時変数自体は可読性を落とす要因にもなるので
バランスを考えてのことになる。
特に宣言と使用箇所が分離するようだとまずい。