[C/C++] FILE 에 대하여 질문이 있어요.
글쓴이: ck7683 / 작성시간: 금, 2014/10/10 - 7:27오후
FILE *fp;
fopen_s(&fp, "input.txt", "r");
보통 간단하고 쉽게 볼 수 있는 파일 오픈인데
생각해보니까 문득 궁금한게 생겼어요.
보통
변수에 포인터를 달면
int* pt;
그걸 사용하기 위해서 int로 선언된 값의 위치라던가 새로 생성하잖아요?
int a;
int *pt= &a;
-
int *pt = new int;
그런데 FILE은 왜 FILE* 로 생성하라고 배우는 거고
왜 대부분 파일과 관련된 함수들은 FILE 를 인수로 받기보단 FILE*를 인수로 받나요?
fscanf, fgets, fputs, fprintf
파일 오픈 하는 함수(fopen_s)는 왜 FILE** 로 인수를 받나요?
Forums:
간단히 설명드리면..
1. FILE의 사이즈 만큼을 return 할 수 없습니다. FILE *를 return 하면 32비트 머신에서 4바이트만 복사하면 됩니다.
그 이상 사이즈를 C/C++에서 return 할 방법이 없죠. (call by value와 call by reference 찾아보세요 ^^)
2. FILE의 fp를 fopen_s함수에서는 첫번째 인수로 넘겨줍니다.
fopen_s 내부를 추측하면, 넘겨준 첫번째 인수에 함수 내부에서 얻어온 fp를 첫번째 인수에 넘겨줘서 본인 스택을 벗어나게 하겠죠?
2번을 더 잘 이해하고 싶으시면 return으로 값을 돌려주는 함수를 한 번 작성해보세요.
문제는 +1을 해서 출력합니다.
ex) 10일 경우 +1을 해줍니다. 그 후에 값을 출력하면 됩니다.
int number = 10;
sum_one(&number); // sum_one 함수는 return이 void여야만 하고, 입력으로 받은 number 값에 +1을 해줍니다.
printf("%d", number);
이것이 원할히 동작하도록 sum_one함수를 만들어보면 됩니다.
1번 답변에 대하여 의문점이 있어요.
2번은 1번에 질문과 연관되어 있어요.
FILE 로 만들어서 FILE* 로 넘겨주면 안되나는 뜻이었어요.
그런데 1번은 제가 이해 안되는게...
__int64 Test(){
return 200010001000;
}
__int64 Test3(__int64 n){
return n;
}
int main(void){
__int64 k = Test();
k = Test3(k);
위에 코드처럼 쓰면
return으로 64비트를 사용했고
인수로도 64비트를 사용했는데.
정상적으로 k값이 200010001000 으로 읽히네요.
음 그리고
struct ABCD{
int a, b, c, d, e, f,g,h,i,j,k;
};
typedef struct ABCD ABCD;
ABCD Test(ABCD a) { return a; }
int main()
{
ABCD a, b;
a.a = 1, a.b = 2, a.c = 3, a.d = 4, a.e = 5, a.f = 6, a.k = 10;
printf("%d", sizeof(a));
b = Test(a);
printf("%d", sizeof(FILE));
//int a[10] = { 0 };
//InputData(a);
return 0;
}
FILE 쫓아가보니 어떤 구조체 이길래
4바이트를 넘어 FILE의 사이즈보다도 큰걸 썼을 때, 어떤 문제가 발생하나 확인하려고 했는데
b.k 가 10으로 제대로 나오드라구요.
그럼 FILE 사이즈 그대로 리턴해도 문제가 안 생길것 같아서
1번의 답변이 이해가 어려워요
> 1. FILE의 사이즈 만큼을 return 할 수
> 1. FILE의 사이즈 만큼을 return 할 수 없습니다. FILE *를 return 하면 32비트 머신에서 4바이트만 복사하면 됩니다.
> 그 이상 사이즈를 C/C++에서 return 할 방법이 없죠. (call by value와 call by reference 찾아보세요 ^^)
완전히 잘못된 이야기입니다.
C/C++의 함수는 어떤 크기의 데이터도 반환할 수 있습니다.
아 제가 잘못이해하고 있었네요;;;
윗분 말씀대로 어떤 크기의 데이터도 반환할 수 있습니다.
1번 정정해서 다시 설명드리면...
return 시에 동작은 다음과 같습니다.
불려진 함수에 원함수로 값을 전달해 줘야 하는데요.
특정한 공간에 값을 넣게 됩니다.
이 특정한 공간의 크기는 32비트 머신에서 4바이트정도 됩니다.
그 이상의 크기인 경우에는 다른 메모리에 데이터를 저장해서... return으로 그 메모리의 주소값을 전달합니다.
*는 32비트 머신에서 4바이트 정도이기때문에 포인터로 전달하면 특정한 공간만 사용하면 되지만,
그 이상의 크기인 경우에는 한번더 작업을 수행하게 됩니다. (머신별로 다를 수도 있습니다.)
추가로 struct를 바로 assign을 할 경우에 대한 작업도 원함수에서 해줘야 하는데요.
struct에서 오퍼레이터를 구현해보진 않았지만... 아마 가능하지 않을까 합니다.
그 작업을 추가로 수행햐아 하니
성능상의 이슈로 포인터를 전달하게 됩니다.
성능상의 이슈보다는 추상화 개념으로 보시면
성능상의 이슈보다는 추상화 개념으로 보시면 됩니다.
사용자 입장에서는 해당 포인터가 FILE* 것만 알고 있으면 제공되는 파일입출력 함수를 쓸 수 있고, FILE 구조체의 내부에 대해 알 필요가 없습니다.
두 분 설명 감사합니다.
성능과 추상화 토끼 두 마리 다 잡는다고 보면 되겠군요
댓글 달기