실행시 오류관련 faq
- C 에서는 둘은 같은 표현입니다.
void main()
{
exit(0);
}
int main()
{
return 0;
}
- C++ 에서는 함수의 타입 체킹을 엄격히 합니다. main 함수의 타입은 int 가 표준 입니다.
int main()
{
return 0;
}
형을 사용하지 않는 경우 int 로 간주하므로 이렇게 하여도 됩니다.
main()
{
return 0;
}
cin ,scanf , cout , printf 함수를 사용하여 제출 합니다.
- 파일 입출력으로 프로그램 하는 경우
제출시
//fi = fopen("input.txt","r");
//fo = fopen("output.txt","w");
fi = stdin;
fo = stdout;
문제에서 입력 , 출력이라고 되어 있는 것은 출력하면 안됩니다.
(1)초기화 문제에서 발생하는 경우가 많습니다.
예를 들어 , 7 개의 배열에서 최대값을 찾는 문제입니다.
#include <stdio.h>
int main()
{
int a[]={6,2,9,8,3,4,7};
int i,max;
for( i = 0 ; i < 7 ; i++){
if ( max < a[i] )
max = a[i];
}
printf("%d\n",max);
}
VISUAL C dubug mode 에서는 정상적인 답 9 가 나옵니다.
하지만 linux 에서 실행하면 정상적인 답이 나오질 않습니다.
왜냐하면 max 의 초기치가 주어지질 않았습니다.
이 경우 VC(Visual C) 에서 release mode(build 메뉴의 configuration 에서 세팅가능) 로 실행하면 9 가 나오질 않습니다.
즉 이런 문제가 발생하는 경우 먼저 자기 컴에서 release 모드로 실행해서 정상적인 답이 나오는지 확인해
보십시요.
(2) 배열의 범위를 넘기는 경우(memory out of bound)도 이런 상황이 발생합니다.
vc 보다 gcc 는 메모리 침범을 엄격하게 검사합니다.
int a[10];
a[10] = 9; // 배열의 인덱스를 0 ~ 9 범위를 넘기는 경우
(3) VC 와 gcc 가 내부적으로 실수를 처리하는 방식이 다릅니다.
컴퓨터내에서 실수를 표현하는데 유한한 자리와 수체계로 인하여 어느정도의 오차 범위내에서 수를 비교하는게 안전 합니다.
두 실수 a,b 가 같은 경우
if ( a == b ) ..
보다는
if ( fabs( a - b) < DBL_EPSILON ) ....
fabs 두 실수의 절대값 구하는 함수이고 두 수의 차가 double 형의 오차의 한계
DBL_EPSILON 보다 작으면으로 가는게 안전한 코딩 입니다.
여기에서 fabs 는 math.h 에 DBL_EPSILON 은 float.h 에 정의가 되어 있습니다.
입력 데이터가 하나인 경우는 입력데이터를 보이질 않게 해 놓았습니다.
제출 후 다음과 같이 나오는 경우 입니다.
---- multiple dataset ----
이런 문제는 입력 데이터 하나에 여러개의 데이터가 걸린 경우 입니다.
온라인 채점 사이트중에 틀린 경우 입력데이터를 보여주는 사이트(usaco) 가 있고 대다수의
저지사이트(pku,uva,spoj...)에서는 입력데이터를 보여 주질 않습니다.
두 가지 모두 장단점이 있습니다.
이런 문제는 힘들지만 데이터를 보지 않고 소스를 다시 한 번 검토 해 보세요.
참고로 이런 유형의 문제에서 입출력시 입력을 받아 처리한 후 결과를 배열에 넣고
마지막에 모두 출력해도 되지만 입력 사이즈가 명시되지 않은 경우가 많기 때문에
아래와 같은 식으로 처리를 해 주세요.
- 입력
- 처리 후 바로 출력
- 입력
- 처리 후 바로 출력
- ...
출력 값을 배열에 넣은 후 한 꺼번에 출력할 필요가 없습니다.
java 로 제출시 주 클래스명은 Main
언어 특성 상
- Java, Python은 명시된 시간의 4 배,
- Perl 언어 특성상 제한 시간은 별 의미가 없을 것 같지만 주어진 시간의 10 배를 주었습니다
제한 시간이 너무 가혹하다고 생각되면 해당 문제명을 알려주세요. 검토 후 제한시간을 늘리겠습니다.
리눅스 컴파일러(gcc) 관련 faq
| 선언 | 입력 | 출력 |
vc | __int64 n | scanf("%I64d",&n) | printf("%I64d",n) |
gcc | long long n | scanf("%lld",&n); | printf("%lld",n) |
* long long 이 표준 입니다.
gcc 에서 abs 함수는 math.h 가 아닌 stdlib.h 를 include 해야 합니다.
gcc 에서는 fflush 를 사용하지 마세요.
♣ itoa 함수는 sprintf 를 이용하면 됩니다.
char buf[100];
int a=123; // 정수123 을 문자열로 변환
sprintf(buf,"%d",a); // 혹은 snprintf(buf,sizeof(buf),"%d",a);
♣ strrev 함수도 직접 작성해서 사용해야 합니다.
여러분들의 나중 프로그래밍 환경이 windows 가 되리란 보장이 없습니다.
보통 vc 환경에서 프로그래밍 하니 그 쪽 환경은 잘 아실 테니까 gcc 에서는 어떤가 하는 기분으로 프로그래밍
해 보세요.
기타 faq
이 회원은 더블릿 게시판 , 이메일,카톡등으로(운영하면서 좋은 방법이 있나 고민) 질문이 있을 경우 관리를 받을 수 있습니다. 온라인에서 선생님을 두는 회원 입니다. 선생님은 일단 제가 한 번 해 보겠습니다.
학생 회원: 월 5 만원
이 회원은 정회원 ,쭈욱 회원과는 별개 입니다.
- 6 만원 입급
- 첫 페이지(30위안)로 진입(들어왔다 빠지더라도 유지)
or 조건 입니다.
- 로긴 후 정보 수정 -> 카테고리에서 변경 하세요.
- 오픈 문제에 한 해서 문제를 푼 후 다른 분들의 소스를 볼 수 있습니다.
- 해당 문제를 게시한 사람은 그 문제에 대한 소스코드를 볼수 있는 권한이 주어집니다.
- 운영자의 판단 하에 어떤 문제에 대한 보기 권한을 줄 수도 있습니다.
알고리즘은 시간과의 싸움이니 각 문제당 요구하는 제한 시간이 우측 상단에 제시되어 있습니다. 테스트 별 이 제한시간을
넘어가면 발생하는 오류 입니다. 이 경우 더 좋은 알고리즘을 생각하거나
간혹 무한 루핑에 빠져서 이 오류를 발생하는 경우도 있으니 이 부분도 같이 체크 해보세요.
그리고 제출 현황에 있는 경과시간은 각 테스트별 경과시간을 합친 시간입니다.
푼 사람에 한해서 소스를 공개하는 문제 입니다.
답이 유일하지 않은 문제 입니다.
our answer 로 뿌려 주는 것은 그 중 한 가지를 제시하는 것이고 제출시 반드시 그렇게
출력하지 않아도 답이 이상없다면 틀린 답으로 간주하지 않습니다.
두 수...스페셜 저지 소스입니다.
#include <stdio.h>
// 맞는 답이면 return 0 아니면 return 1
int main()
{
FILE *fi,*fans,*fusr;
int i,j;
int arr[20];
fi = fopen("input.txt","r"); //테스트 데이터
fans = fopen("ans.txt","r"); //정답
fusr = fopen("usr.txt","r");//사용자 답
// 입력 데이터 읽음
for( i = 0 ; i < 20 ; i++){
fscanf(fi,"%d",&arr[i]);
}
// 첫 줄 최대값 비교
int ans,uans;
fscanf(fans,"%d",&ans); // 정답
fscanf(fusr,"%d",&uans); // 사용자 답
if ( ans != uans) return 1;
// 두 번째 줄 두 수 비교
int first,second;
if ( fscanf(fusr,"%d %d",&first,&second) == EOF ) return 1;
if ( first + second != ans) return 1;
// 첫 수가 목록에 있는지 비교
for ( i = 0 ; i < 20 ; i++){
if ( arr[i] == first ) {
arr[i] = -100;
break;
}
}
if ( i == 20 ) return 1;
// 두번째 수가 목록에 있는지 비교
for ( i = 0 ; i < 20 ; i++){
if ( arr[i] == second ) break;
}
if ( i == 20 ) return 1;
fclose(fi);
fclose(fans);
fclose(fusr);
//모두 통과 맞는 답...
return 0;
}
스페셜저지 문제인데 작업이 안된 문제들이 있습니다. 소스를 짜 주시면 적용하도록 하겠습니다.
오래전 사무실 화장실에 비둘기(dove)들이 집을 지었습니다.
며칠을 두고 보다 주위가 하두 지저분해져서 치워야 겠다고 맘 먹고
둥지를 보니 알이 몇 개 보이더군요.
알을 보니 차마 치울수가 없어 그대로 두었습니다. 열심히 청소하면서...
새끼(let)가 태어나고 조금 지나니 비둘기 가족들이 떠나가더군요.
처음 시작하고 날 때 까지 보살펴 주는 의미로 dovelet 이란 이름이 괜찮은 것 같아서요.
한 김에 let 이 들어가는 영어 공부 하나.
application + let --> applet
분야는 unix process + c + php 쪽으로 공부하셔야 할 것 같습니다.
어려운 쪽은 아닌데 아무래도 사용자 소스를 가져와 실행시켜야 하니 여러가지
예외적인 경우가 많이 발생합니다.
이 부분을 해결하기가 조금 까다로왔습니다.그리고 엄청난 막일...
- 질문(이규호)
c 에서 왜 head 파일이 없어도 fatal error 를 내지 않을까요.
- 답변(makecode)
c언어는 좀 특이한 성격을 가지고 있는데, 변수의 데이터 타입을 정의하지 않으면 무조건 int로 간주(전역, 함수 인자 등에서),
선언되지 않은 함수를 사용했으면 무조건 int를 반환하는 함수로 간주 합니다. putchar, gets, strlen모두 int를(혹은 같은 크기를)
반환하기 때문에 사용해도 별 이상 없습니다.
http://www.cinsk.org/cfaqs/html/node3.html#1.25
- 질문(이규호)
gets 는 리턴 타입이 정수가 아니찮아요
- 답변(makecode)
리턴형이 포인터 이지만 sizeof(char*) == sizeof(int) 이기 때문에
별 이상 없이 동작하는듯 합니다.
- 질문(이규호)
아! 그렇군요.
그러면 일단 4 바이트 짜리 함수는 include 없이 모두 사용
할수 있다는 말은 head 파일은 함수의 원형만 기억하는 용도외
에는 아무 역할도 하지 않나요.
- 답변(makecode)
넵, header는 prototype만 알려주는 역할을 하고 컴파일 할때 적절하게 obj파일을 만들어 준 다음에 그 본체는 library에 들어있어서 링크 할 때 연결 해주니까요 :D
- (이규호)
그렇군요.
가만 생각하니 head 파일 들여다 보니 함수의 원형만 있었던 걸로 기억되네요.
서버의 부하에 따라 경과시간이 조금씩 흔들립니다. 채점 시스템에서
가장 빨리 보완해야 할 부분 입니다. 계속 고민해 보겠습니다.
- linux
- gcc version 4.8.5 ...코드 최적화 level 은 -O2 로 주었습니다. -> gcc 8.1.0 upgrade(2019.11.8)
- java version "java version "1.8.0_45"
- Python 2.7.5
- perl 5.16.3