C의 함수에서 '구조물' 반환
오늘 나는 몇명의 친구들에게 C의 사용법을 가르치고 있었다.struct
s. 그들 중 한 명이 당신이 a를 돌려줄 수 있는지 물었다.struct
내가 대답한 기능에서: "아니오! 당신은 역동적으로 포인터를 돌려줄 것이다.malloc
에이드struct
대신 s."
C++를 주로 하는 사람으로부터 온 나는 돌아올 수 없을 것으로 예상하고 있었다.struct
s 값으로C++에서는 과부하 할 수 있다.operator =
당신의 물건을 위해 그리고 당신의 물건을 가치로 돌려주는 기능을 가지고 있는 것이 완전히 이치에 맞다.하지만 C에서는 그런 선택권이 없어서 컴파일러가 실제로 무엇을 하고 있는지 생각하게 만들었어.다음을 고려하십시오.
struct MyObj{
double x, y;
};
struct MyObj foo(){
struct MyObj a;
a.x = 10;
a.y = 10;
return a;
}
int main () {
struct MyObj a;
a = foo(); // This DOES work
struct b = a; // This does not work
return 0;
}
나는 왜 그런지 이해한다.struct b = a;
작동하지 않아야 함 - 과부하할 수 없음operator =
데이터 유형.어떻게 그럴 수가 있지?a = foo();
컴파일은 괜찮니?struct b = a;
과 같은 을 던질 수 있다 어쩌면 다음과 같은 질문을 해야 할지도 모른다.정확히 무엇을 말하는가?return
와 관련된 한 진술.=
사인 do?
할 수 의 구하하하 ( (?=
운영子) 문어(文語)文語(는 잘 정립된 부분이다그것은 언어에서 잘 정의된 부분이다.에 대한 유일한 문제struct b = a
완전한 유형을 제공하지 않았다는 겁니다.struct MyObj b = a
잘 될 거야구조물을 기능에도 전달할 수 있다. 구조물은 매개 변수 전달, 반환 값 및 할당을 위해 내장 유형과 정확히 동일하다.
여기 세 가지를 모두 수행하는 간단한 시연 프로그램이 있는데, 이 프로그램은 구조를 매개 변수로 전달하고, 기능에서 구조를 반환하며, 할당 설명서에 구조를 사용한다.
#include <stdio.h>
struct a {
int i;
};
struct a f(struct a x)
{
struct a r = x;
return r;
}
int main(void)
{
struct a x = { 12 };
struct a y = f(x);
printf("%d\n", y.i);
return 0;
}
다음 예제는 거의 동일하지만, 내장되어 있는 것을 사용한다.int
프로그램은 전달, 할당 에 대해 두 은 동일하다두 프로그램은 매개변수 전달, 할당 등에 대한 값별 전달과 관련하여 동일한 행동을 가진다.
#include <stdio.h>
int f(int x)
{
int r = x;
return r;
}
int main(void)
{
int x = 12;
int y = f(x);
printf("%d\n", y);
return 0;
}
다음과 같은 전화를 걸 때a = foo();
, 컴파일러는 스택에 있는 결과 구조의 주소를 밀어넣고 그것을 에 "poss" pointer로 전달할 수 있다.foo()
기는 하다 이 될 수 효과적으로 다음과 같은 것이 될 수 있다.
void foo(MyObj *r) {
struct MyObj a;
// ...
*r = a;
}
foo(&a);
단, 정확한 구현은 컴파일러 및/또는 플랫폼에 의존한다.칼 노룸이 지적하듯이, 구조가 충분히 작다면, 그것은 기록부에 완전히 다시 기록될 수도 있다.
내가 기억하는 한, C의 첫 번째 버전은 프로세서 레지스터에 들어갈 수 있는 값만 반환할 수 있도록 허용했다. 즉, 구조체에 포인터를 반환할 수 있다는 뜻이다.함수 인수에 적용되는 제한과 동일한 제한.
보다 최신 버전에서는 구조체처럼 더 큰 데이터 객체를 전달할 수 있다.나는 이 특징이 이미 80년대나 90년대 초반에 흔했다고 생각한다.
그러나 어레이는 여전히 통과되고 포인터로만 반환될 수 있다.
구조체를 돌려주는 것은 문제가 되지 않는다.그것은 가치로 전달될 것이다.
그러나 로컬 변수의 주소를 가진 구성원이 구조체에 포함된 경우
struct emp {
int id;
char *name;
};
struct emp get() {
char *name = "John";
struct emp e1 = {100, name};
return (e1);
}
int main() {
struct emp e2 = get();
printf("%s\n", e2.name);
}
자, 여기e1.name
함수의 로컬 메모리 주소 포함get()
. 한번get()
반송하면, 그 지역 주소가 공개되었을 것이다.따라서, 발신자 내에서 우리가 그 주소에 접근하려고 하면, 우리가 자유 주소를 사용하려고 할 때 분할 오류가 발생할 수 있다.그거 안 좋은데..
as thee1.id
그 가치가 복사될 것이기 때문에 완벽하게 유효할 것이다.e2.id
따라서, 우리는 항상 함수의 로컬 메모리 주소를 반환하지 않도록 노력해야 한다.
몰로크 처리된 모든 것은 원하는 때에 반환할 수 있다.
그struct b
구문 오류로 인해 라인이 작동하지 않는다.만약 당신이 타입을 포함하도록 그것을 확장한다면 그것은 잘 될 것이다.
struct MyObj b = a; // Runs fine
여기서 C가 하고 있는 것은 본질적으로 a이다.memcpy
원점에서 목적지까지.이것은 의 할당과 반환 모두에 적용된다.struct
값들)((및 다 모 값 값 값 값 값 )
struct emp {
int id;
char *name;
};
struct emp get() {
char *name = "John";
struct emp e1 = {100, name};
return (e1);
}
int main() {
struct emp e2 = get();
printf("%s\n", e2.name);
}
새로운 버전의 컴파일러와 잘 어울린다.id와 마찬가지로 이름의 내용이 할당된 구조 변수에 복사된다.
그래, 구조와 반환 구조도 통과할 수 있어.네 말이 맞았지만 실제로 MyObj b = a와 같아야 할 데이터 유형을 통과하지 못했다.
사실 나도 포인터나 전역 변수를 사용하지 않고 기능에 대한 둘 이상의 값을 반환할 수 있는 더 나은 해결책을 찾으려 할 때 알게 되었다.
다음은 평균에 대한 학생 점수의 편차를 계산하는 동일한 예다.
#include<stdio.h>
struct marks{
int maths;
int physics;
int chem;
};
struct marks deviation(struct marks student1 , struct marks student2 );
int main(){
struct marks student;
student.maths= 87;
student.chem = 67;
student.physics=96;
struct marks avg;
avg.maths= 55;
avg.chem = 45;
avg.physics=34;
//struct marks dev;
struct marks dev= deviation(student, avg );
printf("%d %d %d" ,dev.maths,dev.chem,dev.physics);
return 0;
}
struct marks deviation(struct marks student , struct marks student2 ){
struct marks dev;
dev.maths = student.maths-student2.maths;
dev.chem = student.chem-student2.chem;
dev.physics = student.physics-student2.physics;
return dev;
}
collelege stack을 위해 arg로 푸시된 구조 var e2 어드레스를 거기에 할당한다.실제로 get()은 eax reg에서 e2의 주소를 반환한다.이것은 참고가 되는 호출과 같다.
C에서 구조체를 지정할 수 있다. a = b;
유효한 구문이다.
당신은 그저 당신의 라인에서 타입의 일부 -- 구조 태그 -- 를 그냥 빼놓았을 뿐이다.
참조URL: https://stackoverflow.com/questions/9653072/return-a-struct-from-a-function-in-c
'IT이야기' 카테고리의 다른 글
VueJs에서 지정된 명명된 슬롯에 어린이를 렌더링하는 방법 (0) | 2022.04.24 |
---|---|
gcc에 128비트 정수가 있니? (0) | 2022.04.24 |
프로그래밍 방식으로 시스템의 코어 수 찾기 (0) | 2022.04.24 |
Vue.js의 프로펠러에 값이 공급되는지 점검하십시오. (0) | 2022.04.24 |
jquery로 업데이트할 경우 Vuejs 바인딩이 작동하지 않음 (0) | 2022.04.24 |