C 언어 가 초기 화 되 지 않 은 부분 변 수 는 얼마 입 니까?
4754 단어 c 언어초기 화 되 지 않 음국부 변수
답 은 종종:
컴 파일 러 와 관련 이 있다4.567917.가능 하지만 0 으로 초기 화 하 는 것 은 보장 되 지 않 습 니 다미 확정.
한 마디 로 모두 진지 한 형이상학 적 인 답 들 로 얄 미 웠 다.
어떤 사람들 이 당신 에 게 끊임없이 컴 파일 러,C 라 이브 러 리,프로세서 시스템 구 조 를 해 주지 만 실제 장면 재현 문 제 를 주지 못 할 때 이 사람 은 큰 확률 로 허튼소리 를 하고 있 습 니 다.
또 금요일 에 집에 돌 아 왔 을 때 버스 에 단문 한 편 을 썼 다.
사실 이 문 제 는 그 자체 가 잘못된 질문 이다.10 만 자 를 말 할 수 있다 고 하면 우 리 는 특정한 장면 에서 그의 특정한 행 위 를 확정 할 수 있다 면 OK 이다.물론 이것 은 비교적 OK 의 실험 을 설계 해 야 한다.
실제 코드 행 위 를 보 여주 기 전에 CPU 는 변 수 를 모 르 고 변수의 이름 을 식별 할 수 없습니다.CPU 는 특정한 메모리 위치 에서 값 을 추출 하거나 특정한 메모리 위치 에 값 을 저장 하기 때문에 변수의 값 이 얼마 인지 물 을 때 이 변수 에 대응 하 는 값 이 어디 에 저장 되 는 지 알 아야 합 니 다.
다음 코드 보기:
#include <stdio.h>
void func1()
{
int a;
printf("func1:%d
", a);
a = 12345;
}
void func2()
{
int b;
printf("func2:%d
", b);
}
void func4()
{
int d;
printf("func3:%d
", d);
}
void func3()
{
int c;
printf("func3:%d
", c);
c = 54321;
func4();
}
void test_call()
{
func3();
}
int main(int argc, char **argv)
{
func1();
func2();
test_call();
}
우 리 는 func 1~func 4 모두 4 개의 함수 가 있 는데 그 내부 에 초기 화 되 지 않 은 부분 변수 가 있 습 니 다.그들의 값 은 도대체 얼마 입 니까?이러한 부분 변수 에 대해 그들의 값 은 다음 과 같다.
검증 은 매우 간단 합 니 다.한번 해 보면 알 수 있 습 니 다.
[root@localhost test]# ./a.out
func1:0
func2:12345
func3:0
func3:0
함수 호출 스 택 프레임 의 변화 에 따라 func 1 의 부분 변수 a 와 func 2 의 부분 변수 b 는 분명히 같은 위치 에 있 습 니 다.func 1 이 호출 될 때 이것 은 새로운 메모리(main 에 들 어가 기 전에 스 택 프레임 이 이 위치 에 도 착 했 을 수 있 습 니 다)입 니 다.a 의 값 은 이 위 치 를 저장 하 는 페이지 에 대응 하 는 오프셋 의 초기 값 에 달 려 있 습 니 다.이것 은 운영 체제 에 달 려 있 습 니 다.운영 체제 가 프로그램 페이지 에 분 배 될 때 페이지 클 리 어 를 0 페이지 로 할 수 있 습 니 다.
스 택 의 분 배 는 C 라 이브 러 리 와 관련 되 지 않 습 니 다.여 기 는 C 라 이브 러 리 의 행위 와 관련 되 지 않 지만 malloc 와 같은 메모리 가 C 라 이브 러 리 와 관련 됩 니 다.
인쇄 결과,a 의 값 은 0 입 니 다.운영 체제 가 응용 프로그램 0 페이지 에 되 돌 아 왔 다 고 생각 합 니 다.그 다음 에 func 1 에서 그 할당 값 12345 이후 함 수 를 되 돌려 줍 니 다.그 다음 에 func 2 를 호출 할 때 이전에 func 1 이 탈퇴 한 스 택 프레임 위치 에서 스 택 프레임 을 재 구축 하고 해당 하 는 위 치 는 12345 입 니 다.
나 는 func 1 의 ret 작업 뒤에 stack 0 의 코드 명령 이 있 는 것 을 보지 못 했다.효율 적 인 고려 도 이런 지령 이 있어 서 는 안 된다.
다시 testcall 함수,분명 합 니 다.func 3 와 func 4 호출 은 같은 스 택 프레임 이 아 닙 니 다.따라서 func 3 에서 c 에 54321 을 부여 하 더 라 도 스 택 프레임 위의 func 4 스 택 프레임 에 대응 하 는 위치 값 d 에 영향 을 주지 않 습 니 다.따라서 c 와 d 의 초기 값 은 모두 0 으로 유지 된다.
그러면 국부 변 수 를 초기 화 하 는 것 과 국부 변 수 를 초기 화 하지 않 는 것 은 지령 차원 에서 어디 에 차이 가 있 습 니까?
간단 합 니 다.직접 보면 알 수 있 습 니 다.국부 변 수 를 초기 화하 지 않 은 func 1 을 먼저 보 세 요.
// int a;
00000000004005ad <func1>:
4005ad: 55 push %rbp
4005ae: 48 89 e5 mov %rsp,%rbp
4005b1: 48 83 ec 10 sub $0x10,%rsp
4005b5: 8b 45 fc mov -0x4(%rbp),%eax
4005b8: 89 c6 mov %eax,%esi
4005ba: bf 90 07 40 00 mov $0x400790,%edi
4005bf: b8 00 00 00 00 mov $0x0,%eax
4005c4: e8 b7 fe ff ff callq 400480 <printf@plt>
4005c9: c7 45 fc 39 30 00 00 movl $0x3039,-0x4(%rbp)
4005d0: c9 leaveq
4005d1: c3 retq
부분 변수 a 를 2222 로 초기 화 하 는 버 전 을 다시 봅 니 다.
// int a = 2222;
00000000004005ad <func1>:
4005ad: 55 push %rbp
4005ae: 48 89 e5 mov %rsp,%rbp
4005b1: 48 83 ec 10 sub $0x10,%rsp
4005b5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
4005bc: 8b 45 fc mov -0x4(%rbp),%eax
4005bf: 89 c6 mov %eax,%esi
4005c1: bf 90 07 40 00 mov $0x400790,%edi
4005c6: b8 00 00 00 00 mov $0x0,%eax
4005cb: e8 b0 fe ff ff callq 400480 <printf@plt>
4005d0: c7 45 fc 39 30 00 00 movl $0x3039,-0x4(%rbp)
4005d7: c9 leaveq
4005d8: c3 retq
명령 이 하나 부족 합 니 다:
4005b5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
초기 화 된 작업 은 실제 명령 에 의 해 이 루어 졌 다.한 마디 로 하면 함수 가 pop 에서 현재 스 택 프레임 을 꺼 낼 때 스 택 프레임 에 남 겨 진 데 이 터 를 정리 하지 않 습 니 다.다음 함수 가 이 스 택 프레임 의 메모리 에 다시 사용 할 때 초기 화 되 지 않 은 부분 변 수 는 데이터 에 영향 을 받 아 불확실 해 집 니 다!
그 러 니 부분 변 수 를 초기 화 하 는 것 을 기억 하 세 요.만약 네가 이렇게 하지 않 는 다 면 하나님 은 결국 너 를 사장 하 실 것 이다.
총결산
여기 서 C 언어 가 초기 화 되 지 않 은 부분 변수 가 얼마 인지 에 대한 자세 한 설명 을 드 리 겠 습 니 다.더 많은 C 언어 가 초기 화 되 지 않 은 부분 변수 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
c 언어 간단한 파일 r/w 조작 방법데이터의 입력과 출력은 거의 모든 C 언어 프로그램과 수반된다. 입력이란 원본에서 데이터를 얻는 것이다. 출력은 단말기에 데이터를 쓰는 것으로 이해할 수 있다.이곳의 원본은 키보드, 마우스, 하드디스크, 시디, 스캐...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.