C 와 범 형
[해석]
컴 파일 환경:
Fedora 10, gcc 버 전 gcc 4.3.2
1 함수 포인터 로 범 형 실현
[코드 목록]
printtest.c
#include <stdio.h>
#include <stdlib.h>
#define DEBUG 0
#define PRINTSTAT( FORMAT, STAT) \
printf("**************** " FORMAT " Test ****************
"\
,STAT);
#define DEBUG_PRINT(FORMAT, VALUE) printf("File %s line %d: "\
#VALUE " = " FORMAT "
"\
,__FILE__, __LINE__,VALUE\
);
enum {
RET_OK,
RET_FAIL
};
typedef int (*FXPrintFun)(void *data);
int print(FXPrintFun _print, void *data)
{
return _print(data);
}
static int print_int(void *data)
{
printf("%d", (int)data);
return RET_OK;
}
static int print_int2(void *data)
{
printf("%d", *(int*)data);
return RET_OK;
}
static int print_float(void *data)
{
printf("%f", *(float*)data);
return RET_OK;
}
static int print_str(void *data)
{
printf("%s", (char*)data);
return RET_OK;
}
int main(void)
{
int i = 0;
float f = 2.6;
char *test = "Generics test!";
int *pi = &i;
float *pf = &f;
#if DEBUG
DEBUG_PRINT("%f", f)
#endif
PRINTSTAT( "%s", "Integer")
for(; i<10; i++)
print(print_int, (void *)i);
printf("
");
PRINTSTAT( "%s", "Integer")
for(i = 0; i<10; i++)
print(print_int2, (void *)pi);
printf("
");
PRINTSTAT( "%s", "Float")
print(print_float, (void *)pf);
printf("
");
PRINTSTAT( "%s", "String")
print(print_str, (void *)test);
printf("
");
return RET_OK;
}
Makefile
OBJS = printtest.o
TARGET = printtest
SRC = printtest.c
all:$(OBJS)
gcc -g $(OBJS) -o $(TARGET)
$(OBJS):printtest.s
gcc -g -c printtest.s -o $(OBJS)
printtest.s:printtest.i
gcc -g -S printtest.i -o printtest.s
printtest.i:$(SRC)
gcc -g -E $(SRC) -o printtest.i
clean:
rm *~ *.o *.s *.i $(TARGET)
* 코드 의 컴 파일, 어 셈 블 리, 링크 과정 을 관찰 하기 위해 Makefile 은 약간 복잡 하 므 로 다음 명령 으로 컴 파일 할 수 있 습 니 다.
gcc printtest.c -o printtest
[운행 결과]
**************** Integer Test ****************
0123456789
**************** Integer Test ****************
0123456789
**************** Float Test ****************
2.600000
**************** String Test ****************
Generics test!
상기 코드 중 하 나 는 주의 할 점 이 있 습 니 다. 정의 할 때 두 가지 print 를 제공 합 니 다.int 함수:
static int print_int(void *data)
{
printf("%d", (int)data);
return RET_OK;
}
static int print_int2(void *data)
{
printf("%d", *(int*)data);
return RET_OK;
}
호출 시간:
int i = 0;
int *pi = &i;
PRINTSTAT( "%s", "Integer")
for(; i<10; i++)
print(print_int, (void *)i);
printf("
");
PRINTSTAT( "%s", "Integer")
for(i = 0; i<10; i++)
print(print_int2, (void *)pi);
printf("
");
print 호출int 시 int 형식 을 void * 형식 으로 강제 변환 합 니 다.print 호출int 2 시 int * 형식 을 void * 형식 으로 강제 전환 합 니 다.놀랍게도 상술 한 두 가지 방법 모두 정확 한 결 과 를 출력 할 수 있다.사실 printint 가 제공 하 는 방법 은 우연 일 뿐 입 니 다. int 는 4 바이트 이 고 void * 유형 도 4 바이트 이기 때문에 강제 변환 에 오류 가 발생 하지 않 았 습 니 다!하지만 플 로 트 타 입 이 라면 printint 와 유사 한 방법 은 안 됩 니 다. gcc 힌트 는 변환 할 수 없습니다.안전 한 방식 은 int * 를 void * 로 바 꾸 고 printint 처리 함수 에서 void * 를 int * 로 변환 한 다음 인용 을 풀 수 있 습 니 다.
2. '\ #' 을 사용한다.
방법 1 이 제공 하 는 코드 에는 '\ #' 의 위력 이 이미 보인다.다음은 범 형의 또 다른 실현 을 살 펴 보 자.
[코드 목록]
printtest.h
#ifndef __PRINTTEST_H__
#define __PRINTTEST_H__
#define GNERIC_PRINT(TYPE,FORMAT,SUFFIX) \
int print##SUFFIX( TYPE data )\
{\
printf(FORMAT, data);\
return 0;\
}
#endif
printtest.c
#include <stdio.h>
#include <stdlib.h>
#include "printtest.h"
#define DEBUG 0
#define PRINTSTAT( FORMAT, STAT) \
printf("**************** " FORMAT " Test ****************
"\
,STAT);
#define DEBUG_PRINT(FORMAT, VALUE) printf("File %s line %d: "\
#VALUE " = " FORMAT "
"\
,__FILE__, __LINE__,VALUE\
);
enum {
RET_OK,
RET_FAIL
};
GNERIC_PRINT(int, "%d", _int)
GNERIC_PRINT(float, "%f", _float)
GNERIC_PRINT(char *, "%s", _str)
int main(void)
{
int i = 0;
float f = 2.6;
char *test = "Generics test!";
#if DEBUG
DEBUG_PRINT("%f", f)
#endif
PRINTSTAT( "%s", "Integer")
for(; i<10; i++)
print_int(i);
printf("
");
PRINTSTAT( "%s", "Float")
print_float(f);
printf("
");
PRINTSTAT( "%s", "String")
print_str(test);
printf("
");
return RET_OK;
}
Makefile
OBJS = printtest.o
TARGET = printtest
SRC = printtest.c
all:$(OBJS)
gcc -g $(OBJS) -o $(TARGET)
$(OBJS):printtest.s
gcc -g -c printtest.s -o $(OBJS)
printtest.s:printtest.i
gcc -g -S printtest.i -o printtest.s
printtest.i:$(SRC)
gcc -g -E $(SRC) -o printtest.i
clean:
rm *~ *.o *.s *.i $(TARGET)
* SRC = printtest. c, SRC = printtest. c printtest. h 가 아 닙 니 다.후 자 는 예 처 리 를 정확하게 완성 하지 못 해 이해 하기 어렵다.이 유 를 설명 할 수 있 는 사람 이 있 습 니까?
채용
gcc printtest.h printtest.c -o printtest
컴 파일 을 진행 하 다
[운행 결과]
**************** Integer Test ****************
0123456789
**************** Float Test ****************
2.600000
**************** String Test ****************
Generics test!
이런 방법 은 매우 멋 있어 보이 지만 코드 의 양 이 많은 상황 에서 실 수 를 하기 쉽다.따라서 함수 포인터 형식 으로 범 형 을 실현 하 는 것 을 추천 합 니 다.
전재 는 출처 를 표시 하고 학습 교류 만 제공 하 며 상업 목적 에 사용 하지 마 십시오.
Copyright @ http://blog.csdn.net/tandesir
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.