サブルーチン
通例、サブルーチンとその呼び出し元の間での引数および戻り値の受け渡しや、サブルーチンが終了したときに呼び出し元にフロー制御を戻すための復帰位置(リターンアドレス)の一時記憶、サブルーチン内のローカル変数の割り当てには、コールスタックやレジスタが使われる。引数がスタックに積まれる順序やメモリレイアウトなどの呼び出し規約は、プログラミング言語やプロセッサ (CPU) のアーキテクチャにも依存するが、コンパイラ固有の修飾子(キーワード)によって指定できる環境もある。x64やARMのように、特定の条件を満たす引数についてはスタックではなくレジスタを経由して受け渡しされるアーキテクチャもある。
環境によっては、呼び出し規約を規定し、また引数と戻り値のデータ型を基本数値型やポインタ型などのPOD(英語版)型に限定することで、異なる言語間で相互運用可能なABI互換性のあるサブルーチンを定義することができる。例えばCで書かれた関数をダイナミックリンクライブラリ (DLL) や共有ライブラリ (so) にエクスポートし、Pascalの関数または手続きとして呼び出したりすることも可能となる。別の例として、Microsoft Excelでは、C/C++やPascalやVisual Basicなどを使ってDLLに実装された関数を、Visual Basic for Applications (VBA) のコードモジュールからプロシージャとして呼び出したり、ワークシートから直接利用したりすることができる。
カーニハンとリッチーによる解説書『プログラミング言語C』、いわゆる「K&R」には、C言語の関数はPascalの「手続き」や「関数」に相当すると書かれてある。つまりC言語では戻り値の有無にかかわらず「関数」(function) と呼んでいる。
関数の定義の書式は次の通りである。
C言語では歴史的な理由から、値を返さない関数を宣言および定義する場合は、関数の型(返戻値の型)を書く場所にvoid(void型)と書く。
関数の宣言が複数ある場合、どの順番で書いても良いし、複数のファイルに分けて書いても良い。ただし、ひとつの関数を複数のファイルに分けて書いてはいけない。
なお、K&RのCはANSI C(C89)として標準化される前の古い仕様に基づいており、Cの歴史を知るうえでは重要だが、2023年現在はISO/IEC 9899規格を参照することが望ましい。