ν°μ€ν 리 λ·°
λ ν νΌμ μ νκ²½ κ°μ¬λμ Secure & Generic C κ°μλ₯Ό λ£κ³ , μ 리ν λ΄μ©μ λλ€.
ν΄λΉ λ΄μ©μ μ μκΆμ μ νκ²½ κ°μ¬λμκ² μμ΅λλ€.
macro function
맀ν¬λ‘ ν¨μλ μ»΄νμΌ μ μ μ μ²λ¦¬κΈ°μ μν΄ ν μ€νΈλ‘ μΉνμ΄ λλ€. λν `argument`μ νμ μ νμ΄ μλ€λ νΉμ§μ κ°μ§κ³ μλ€. μ΄λ‘μ¨ λ§€ν¬λ‘ ν¨μλ νΈλ¦¬ν¨μ μ 곡νμ§λ§, κ°κ³Όν κ²½μ° μ¬λ°λ₯΄μ§ μμ κ²°κ³Όλ₯Ό λ°ννλ―λ‘ μ£Όμνμ¬ μ¬μ©νμ¬μΌ νλ€.
Side effect
#include <stdio.h>
#define TEST(X) ((X) * (X))
int main()
{
int i = 1;
int a = TEST(++i);
}
κ°λ¨νκ² μκ°νμ λ, ν΄λΉ μ½λλ `TEST(X)`μ `++i`κ°μ λμ νλ€λ©΄ 4λΌλ κ°μ΄ λ°νλ κ²μ΄λΌκ³ μκ°νλ€. νμ§λ§ μ΄λ 맀ν¬λ‘ ν¨μλ₯Ό μ μ ν μ΄ν΄νμ§ λͺ»ν κ²μ΄λ€. μ€μ κ°μ `(++i) * (++i)`μ κ°μ΄ λ°νλκ² λλ€.
#include <stdio.h>
#define TEST(I) (I * I * I)
// define TEST(I) ((I) * (I) * (I))
// μΈμλ§λ€ κ΄νΈλ‘ λ¬Άμ΄μΌ μνλ κ²°κ³Όλ₯Ό μ»μ μ μμ.
int main()
{
int a = TEST(2 + 1);
// int a = 2 + 1 * 2 + 1 * 2 + 1λ‘ λ¨. (κ·Έλλ‘ νλ¦Ό.)
printf("a = %d\n", a);
return 0;
}
λ§μ½ μΉνλΆμ κ΄νΈλ₯Ό μ μ©νμ§ μλλ€λ©΄ μμ κ°μ΄ μμ΄ν κ²°κ³Όλ₯Ό μ§λ©΄ν μ μλ€. μ΄λ μ°μ°μμ μ°μ μμ μ μ©κ³Ό ν¨κ» 맀ν¬λ‘ ν¨μλ‘ κ·Έλλ‘ κ°λ€μ΄ νλ €λ²λ¦¬κΈ° λλ¬Έμ΄λ€. μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μλ μ μ ν κ΄νΈλ₯Ό μ¬μ©νμ¬ μ°μ μμλ₯Ό μ§μ ν΄μ£Όμ΄μΌ νλ€.
for (inti = 0; i < 1000; i++) {
abc();
}
μμ κ°μ΄ λ°λ³΅λ¬Έ λ΄μμ ν¨μκ° μ§μμ μΌλ‘ νΈμΆλ κ²½μ°, `abc()`κ° λ§€ν¬λ‘ ν¨μμ΄λ©΄ μ΄λ¨κΉ? 맀ν¬λ‘ ν¨μμ κ²½μ° λΆλ¦¬λ κ³³μμ μ½λκ° κ·Έλλ‘ λ€μ΄κ°κΈ°μ ν¨μ¨μ μ΄λ€.
local? global?
#include <stdio.h>
size_t count = 0;
#define EXEC_BUMP(func) (func(), ++count)
void g(void)
{
++count;
}
void aFunc(void)
{
size_t count = 0;
while (count++ < 10)
{
EXEC_BUMP(g);
// μΌλ°μ μΌλ‘λ λ³μλͺ
μ΄ μΌμΉνμ§ μλ€λ©΄, extern λ³μλ₯Ό μ°Έμ‘°νκ² μ§λ§
// 맀ν¬λ‘ ν¨μκ° μ½λλ΄μ νλ¦¬κ² λλ©΄μ auto variableμ μ°Έμ‘°νκ² λ¨.
}
}
int main()
{
aFunc();
return 0;
}
맀ν¬λ‘ ν¨μκ° νΈμΆλλ μμΉμμ μ½λκ° κ·Έλλ‘ λ€μ΄κ°κ² λλ νΉμ±μ μ΄ν΄νλ€λ©΄ μμ κ°μ λ¬Έμ μ μ§λ©΄ν μ μλ€λ κ²μ μ μ μλ€. λ³μλ₯Ό μ°Ύλ κ²½μ° `local variable`μμ `global variable` μμΌλ‘ μ°Ύκ² λλ€. λ€λ₯΄κ² νλ¨νλ€λ©΄, 맀ν¬λ‘ ν¨μλ `global variable`μ μ°Έμ‘°ν κ²μ΄λΌκ³ μκ°λμ§λ§ `local variable`μ μ°Έμ‘°νλ€.
#include <stdio.h>
size_t count = 0;
void g(void)
{
printf("g() νΈμΆ, count = %u.\n", ++count);
}
typedef void (*exec_func)(void); // ν¨μ μ£Όμλ₯Ό λ°λ type μ§μ .
// parameterλ‘ ν¨μ μ΄λ¦μ fλ‘ λμ΄μ μ¬μ©κ°λ₯νλλ‘.
inline void exec_bump(exec_func f) {
f();
++count;
}
void aFunc(void)
{
size_t count = 0;
while (count++ < 10)
{
exec_bump(g);
// typedefλ₯Ό ν΅ν΄ g ν¨μ μμ μ£Όμλ₯Ό μ λ¬.
}
}
int main()
{
aFunc();
getchar();
return 0;
}
μ μμ±ν μ½λλΌλ©΄ μ€λ³΅λλ μλ―Έμ λ³μλ₯Ό κ°μ§λ κ²μ μ’μ§ μλ€. νμ§λ§ μμ μν©μ μ§λ©΄νμ§ μκΈ° μν΄μλ `typedef`λ₯Ό νμ©νλ©΄ μνλ κ²°κ³Όλ₯Ό μ»μ μ μλ€.
맀ν¬λ‘λ‘ μ§μ ν ν¬μΈν°
#define cstring char *
int main() {
csting ap, bp;
}
μ΄ μ½λμμ μνλ κ²°κ³Όλ `char *ap`, `char *bp`μ΄λ€. νμ§λ§ `char *ap`, `char bp`κ° μ μΈλλ€. λ¬Όλ‘ μ μ ν μ½λ© μ€νμΌμΌ κ²½μ° μ΄μ κ°μ΄ ν μ€μ μ¬λ¬ κ°λ₯Ό μ μΈνλ κ²μ μ λͺ»λμλ€. μνλ κ²°κ³Όλ₯Ό μ»κΈ° μν΄μλ `typedef char * csting`μΌλ‘ μ μΈνμ¬μΌ νλ€.
#/## μ°μ°μ νμ©
`#` μ°μ°μμ κ²½μ° `#define`μμ μ¬μ©νλ κ²μμ μ μ μλ―μ΄, ν ν°μ ν μ€νΈν μμΌμ£Όλ κΈ°λ₯μ μννλ€. μ΄μ λ¬λ¦¬ `##`μ κ²½μ° ν ν°μ λ³ν©μμΌμ£Όλ κΈ°λ₯μ μννλ€.
#define PRN(x, type) type##Print(x)
void charPrint(char);
void shortPrint(short);
void intPrint(int);
int main()
{
char ch = 'A';
short s = -1;
int i = 2147483647;
PRN(ch, char);
PRN(s, short);
PRN(i, int);
return 0;
}
μ΄λ₯Ό μ μ ν νμ©νλ€λ©΄, `type`μ λ°λΌ ν¨μλ₯Ό νΈμΆνμ§ μκ³ `argument`λ§ λ¬λ¦¬ νλ μμΌλ‘ ν¨μλ₯Ό νΈμΆνλ κΈ°λ₯μ λ§λ€ μ μλ€.
μ¬λ¬ μ€μ 맀ν¬λ‘
#include <stdio.h>
#define SWAP(x,y) \
tmp = x; \
x = y; \
y = tmp
int main()
{
int x, y, z, tmp = 0;
printf("x = "); scanf("%d", &x);
printf("y = "); scanf("%d", &y);
printf("z = "); scanf("%d", &z);
if (z == 0) SWAP(x, y);
printf("x = %d, y = %d, z = %d\n", x, y, z);
return 0;
}
Cμ½λλ₯Ό μμ±ν λ νν, `if`μμ ν μ€μ μ½λλ₯Ό μ€νμν€κ³ μ νλ€λ©΄ μμ κ°μ΄ μμ±νλ€. νμ§λ§ μμ μΈκΈνμλ―μ΄ λ§€ν¬λ‘ ν¨μλ νΈμΆλ μμΉμμ μ½λκ° μ§μ λ€μ΄κ°λ€λ νΉμ§μ κ°μ§κ³ μλ€. λ°λΌμ μ΄λ₯Ό λ³κ²½νλ©΄ λ€μκ³Ό κ°λ€.
int main()
{
if (z == 0)
//SWAP νΈμΆ
tmp = x;
x = y;
y = tmp;
}
μ¦ ifλ¬Έμ μ±κ³΅ μ¬λΆμ μκ΄ μμ΄ μλμ μ½λλ 무쑰건 μννκ² λλ€. λ°λΌμ `if (z == 0) { SWAP(x, y); }`λ₯Ό μ¬μ©νλ€.
do { \
tmp = m; \
x = y; \
y = tmp; \
} while (0)
μ€κ΄νΈ μμ΄ μ¬μ©νκ³ μ νλ€λ©΄, 맀ν¬λ‘λ₯Ό `do-while`λ‘ κ°μΈ μ€μΌλ‘μ¨ λμΌν κΈ°λ₯μ μννλλ‘ ν μ μλ€.
macro vs const
μμλ₯Ό μ μΈν λλ 2κ°μ§ λ°©λ²μ μ¬μ©νλ€. νλλ `macro`μ΄κ³ νλλ `const`μ΄λ€. λ κ°μ§ λͺ¨λ μμμ΄μ§λ§ μ΄λ€ λͺ©μ μΈκ°μ λ°λΌ λ€λ₯΄κ² μ¬μ©ν μ μλ€.
#define PI 3.14
// νμΌ λ΄μ λͺ¨λ ν¨μμμ κ°μ κ°μΌλ‘ μ°κ³ μΆλ€λ©΄, μ£Όμμ°Έμ‘° λΆκ°.
const doulbe 3.14
// κ°μ νμΌ λ΄μ ν¨μλ³λ‘ μμλ₯Ό μ μΈνκ³ μ νλ κ²½μ°
μ¦ `macro`λ₯Ό ν΅ν΄ μ μΈλ μμμ κ²½μ° νμΌ λ΄μ λͺ¨λ ν¨μμμ μ μ©ν μ μλ κ°μ μ μΈν κ²½μ°μ μ¬μ©ν μ μλ€. μ΄μ λ¬λ¦¬ `const`μ κ²½μ° κ°μ νμΌ λ΄μ ν¨μ λ³λ‘ μμλ₯Ό μ μΈνκ³ μ νλ κ²½μ°μ μ μ ν μ΄μ©λ μ μλ€.
'πββοΈ νλ‘κ·Έλλ° μΈμ΄ > C' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
C: Generic Coding (0) | 2020.11.18 |
---|---|
C: λ€μν ν¬μΈν° (0) | 2020.11.17 |
C: μ μμ λ²μ (0) | 2020.11.16 |
C: ννμ (0) | 2020.11.14 |
C: μ μΈκ³Ό μ΄κΈ°ν (0) | 2020.11.14 |