C 언어 에서 "포인터" 가 "함수 인자" 일 때 주의사항

5959 단어 C
C 언어 에서 "포인터" 가 "함수 인자" 일 때 주의사항
    C 언어 에서 지침 은 가장 습득 하기 어 려 운 지식 중 하나 입 니 다. 그러나 일반적인 교재 에서 지침 을 비교적 상세 하 게 설명 합 니 다. 만약 에 여러분 이 C 에서 지침 에 대한 상세 한 지식 을 깊이 배우 고 싶다 면 을 보 시 는 것 을 추천 합 니 다. 또는 을 참고 하 셔 도 됩 니 다. 이 책 들 은 C 언어 에 대한 설명 이 매우 깊이 있 습 니 다.기본 교재 보다 좀 더 깊이 있 게 말 하면 한 번 볼 수 있다.
    본론 으로 돌아 가면 본 글 의 주요 목적 은 제 가 프로젝트 를 할 때 겪 은 문 제 를 여러분 과 공유 하 는 것 입 니 다. 즉, 지침 이 함수 매개 변수 로 서 이 함 수 를 통 해 이 지침 에 메모 리 를 분배 하려 고 할 때 발생 하 는 문제 입 니 다. 초보 자 들 이 보기에 이것 은 문제 가 없 을 수도 있 고 자 연 스 럽 게 사용 되 고 있 습 니 다.그러나 이 문 제 는 제 가 한 프로젝트 에 큰 버그 가 생 겼 고 최종 적 으로 디 버 깅 수단 을 통 해 이 문 제 를 찾 았 습 니 다. 다음은 코드 와 서술 을 통 해 상세 하 게 설명 하 겠 습 니 다.
    우 리 는 항상 이러한 함 수 를 만 날 수 있 습 니 다. 예 를 들 어 하나의 포인터 에 메모 리 를 분배 하고 메모리 의 변 수 를 초기 화 합 니 다. 이 지침 은 일반적으로 비교적 완선 한 구조 체 지침 이나 다른 복잡 한 지침 입 니 다. 이 함 수 는 보통 mallocAndInit () 라 고 명명 합 니 다.구체 적 인 형식 은 다음 에 나 올 것 입 니 다. 그러면 이 함수 의 첫 번 째 버 전 을 살 펴 보 겠 습 니 다. 여러분 은 먼저 '버 전 1' 이 잘못 되 었 는 지 볼 수 있 습 니 다.
//   1
#include 
#include 
#include 

#define LEN 20

typedef struct person 
{
	char name[LEN];
	int  age;
}person;

//   0    ,  1    
int mallocAndInit(person *pPs)
{
	pPs = (person*)malloc(sizeof(person));

	if (NULL == pPs)
	{
		//       
		fprintf(stderr, "Malloc failed.
"); return 0; } // pPs->age = 0; strcpy(pPs->name, ""); return 1; } void main() { person *pTest = NULL; if (!mallocAndInit(pTest)) { fprintf(stderr, "Error.
"); exit(1); } // , ? printf("The person's name is %s, age is %d.
", pTest->name, pTest->age); if (pTest != NULL) { free(pTest); pTest = NULL; } }

    '버 전 1' 에서 person 구조 체 를 정 의 했 는데 그 중에서 몇 가지 설명 이 필요 합 니 다.
    1. 배열 의 길 이 는 일반적으로 매크로 정 의 를 사용 하여 후속 프로젝트 가 비교적 클 때 수정 하 는 데 편리 하 다.
    2. 프로그램 에서 가능 한 한 잘못된 통 제 를 하 는 것 이 좋 습 니 다. 예 를 들 어 위의 메모리 배분 이 성공 적 인지 판단 하고 함수 호출 후 기대 하 는 목적 을 달성 하 는 지 판단 하 는 것 입 니 다.
    3. typedef 를 사용 하여 정 의 를 간소화 합 니 다.
    4. NULL = = = pps 를 사용 합 니 다. pps = = NULL 을 사용 하 는 것 은 좋 은 프로 그래 밍 습관 입 니 다. 일부 면접 에서 도 "=" 을 "=" 로 잘못 썼 을 때 전 자 는 직접 컴 파일 오류 가 발생 하고 후 자 는 실 행 될 수 있 기 때 문 입 니 다. 이러한 은밀 한 오 류 는 전체 항목 에 혼란 을 초래 할 수 있 습 니 다. 이러한 BUG 는 가끔 발견 되 기 어렵 습 니 다.그래서 이 습관 은 매우 중요 하 다. 한 마디 로 '판단 할 때 등호 왼쪽 에 상수, 등호 오른쪽 에 변 수 를 써 서 등호 가 가 져 오 는 심각 한 BUG 를 적 게 쓰 지 않도록 한다' 는 것 이다.
    5. 마지막 으로 지침 을 사용 하고 메모 리 를 방출 해 야 합 니 다. 그렇지 않 으 면 메모리 유출 등 문제 가 발생 할 수 있 습 니 다.
    우리 의 주제 로 돌아 가면 '버 전 1' 에 심각 한 오류 가 발생 했 습 니 다. 그리고 발견 되 기 어렵 습 니 다. 컴 파일 할 때 오류 가 발생 하지 않 지만 실행 할 때 오류 가 발생 할 수 있 습 니 다. 이 상황 이 발생 하면 이 지침 이 내부 에 배치 되 었 는 지 한 단계 디 버 깅 할 수 있 습 니 다.
    왜 틀 렸 을 까?우리 가 분석 해 보 자. 우 리 는 한 가지 문 제 를 알 아야 한다. 포인터 변 수 를 함수 매개 변수 로 전달 할 때 포인터 변수 자체 의 주소 값 을 수정 해 야 할 때 우리 가 흔히 말 하 는 '값 전달' 에 해당 한다. 모두 가 알다 시 피 값 전달 은 실제 인삼 의 값 을 바 꾸 지 않 는 다. 흔히 볼 수 있 는 예 는 하나의 함수 로 두 변수의 값 을 교환 하 는 것 이다.이 점 에 대해 궁금 한 점 이 있다 면 기본 교재 에서 함수 형 삼 과 실 삼 관련 장 을 살 펴 보 는 것 이 좋 습 니 다. 상세 한 소개 가 있 을 것 입 니 다.다시 말 하면 포인터 의 주소 값 을 수정 해 야 하 는 함수 의 실제 인삼 에 대해 우 리 는 '값 전달' 에 해당 합 니 다. 그래서 우 리 는 mallocAndInit () 함 수 를 호출 한 후에 실제 main 함수 의 포인터 pP 가 할당 되 지 않 은 메모리 의 지침 입 니 다. 이때 우 리 는 printf 함 수 를 호출 하여 이 포인터 의 내용 에 접근 하 는 것 은 잘못된 것 입 니 다.이것 은 알 수 없 는 메모리 에 접근 한 것 과 같 기 때문에 매우 위험한 조작 이다.중 시 를 불 러 일 으 켜 야 한다.요약 하면 한 마디 로 함수 매개 변수 에서 포인터 매개 변수의 주소 값 을 함수 로 수정 해 야 할 때 포인터 의 값 전달 작업 에 해당 합 니 다. 일반적인 변수 값 전달 과 같은 결과 입 니 다. 함수 로 함수 매개 변수 에서 포인터 매개 변수의 내용 (예 를 들 어 person 중의 age 값 수정) 을 방문 하거나 수정 할 때 이것 은 주소 전달 에 해당 합 니 다.실제 인삼 결 과 는 수정 되 어 함 수 를 전달 할 수 있다.다음은 두 가지 해결 방안 을 제시 합 니 다. 1. 함수 내부 에서 포인터 에 메모 리 를 분배 한 후 이 포인터 로 분 배 된 주 소 를 되 돌려 줍 니 다. "버 전 2" 를 보십시오.2. 함수 에 2 급 지침 을 전달 하여 1 급 지침 의 주소 값 을 수정 합 니 다. 그러면 비교적 번 거 로 울 수 있 습 니 다. "버 전 3" 을 보십시오.
 
//   2
#include 
#include 
#include 

#define LEN 20

typedef struct person
{
	char name[LEN];
	int  age;
}person;

//   NULL    ,        
person* mallocAndInit(person *pPs)
{
	pPs = (person*)malloc(sizeof(person));

	if (NULL == pPs)
	{
		//       
		fprintf(stderr, "Malloc failed.
"); return NULL; } // pPs->age = 0; strcpy(pPs->name, ""); return pPs; // !!! } void main() { person *pTest = NULL; // !!! if (!(pTest = mallocAndInit(pTest))) { fprintf(stderr, "Error.
"); exit(1); } // printf("The person's name is %s, age is %d.
", pTest->name, pTest->age); // if (pTest != NULL) { free(pTest); pTest = NULL; } }
//   3
#include 
#include 
#include 

#define LEN 20

typedef struct person
{
	char name[LEN];
	int  age;
}person;

//   0    ,  1    
int mallocAndInit(person **ppPs)
{
	*ppPs = (person*)malloc(sizeof(person));

	if (NULL == *ppPs)
	{
		//       
		fprintf(stderr, "Malloc failed.
"); return 0; } // (*ppPs)->age = 0; strcpy((*ppPs)->name, ""); return 1; } void main() { person *pTest = NULL; person **pptest = &pTest; // !!! // , if (!mallocAndInit(pptest)) { fprintf(stderr, "Error.
"); exit(1); } // printf("The person's name is %s, age is %d.
", pTest->name, pTest->age); // if (pTest != NULL) { free(pTest); pTest = NULL; pptest = NULL; } }

    한 마디 로 C 언어의 지침 은 확실히 비교적 골 치 아 프 고 지침 으로 인해 여러 가지 문제 가 자주 발생 하기 때문에 항상 경계해 야 하 며 지침 에 부 딪 히 면 고도 로 세심 해 야 한다.   
    위의 프로그램 은 여러분 이 직접 복사 하여 VS 에 붙 여 넣 을 수 있 고 직접 실행 할 수 있 습 니 다. 모두 제 가 검증 한 후에 보 낸 것 입 니 다. 모 르 는 부분 이 있 으 면 여러분 의 메 시 지 를 환영 합 니 다. 제 가 보고 바로 답장 을 드 리 겠 습 니 다. 이것 은 첫 번 째 편 입 니 다. 비교적 많이 쓰 고 상세 하 며 여러분 들 이 자세히 음미 하고 교류 할 친구 가 있 으 면 메 시 지 를 환영 합 니 다. 감사합니다.

좋은 웹페이지 즐겨찾기