4일차 - C언어

JeongChaeJin·2021년 4월 15일
0

한컴아카데미

목록 보기
1/6

함수

  • "인자 변수"는 Stack에 쌓이고 (호출 시), 함수 끝나면 소멸한다.
int F1(void) {
	return 100, 200, 300 // 300 return
}
  • ,로 나열되어있으면 맨 오른쪽만 return

함수간 데이터 공유

  • 포인터 *연산, 배열의 []연산
  • *p = 11; *(p + 0) = 11; p[0] = 11; 포인터의 배열표현
  • arr[0] = 11; *(arr + 0) = 11; *arr = 11; 배열의 포인터 표현
  • 배열을 함수로 넘길 때, 배열의 시작주소만 넘기면 된다.
int main(){
	char arr[4] = {4, 8, 8, 5};
    Func(arr); // arr이 주소이므로 &arr 아님
}

int Func(char *ptr){
    *ptr = 3;
    *(ptr + 1) = 6;
    ptr[2] = 9;
}
  • badcase
void Func(int *ptr){
    int size;
    
    size = sizeof(ptr) / sizeof(ptr[0]) // 1
 	return;
}

int main(){
    int arr[7] = {0};
    Func(arr);
}
  • ptr은 arr의 첫 주소 이므로 sizeof(ptr)이 4byte가 나온다.

다양한 포인터 형태

  • Compiler는 이름 기준 오른쪽 방향 해석 -> 왼쪽 방향 해석

    • []는 배열 타입, * 포인터 타입, () 함수 타입

    int arr[5]

      1. arr[ : 음 arr은 배열 타입이군
      1. [5] : 음 arr은 요소가 5개군 -> 오른쪽 이제 없음(왼쪽 방향 해석)
      1. int : 5개 요소들이 int 타입이군

    int *ptr

      1. (오른쪽 아무것도 없으므로 왼쪽 해석) * :음 포인터 타입이군
      1. int : 음 int에 대한 주소를 가리키는군

    int *pArr[3] (포인터 배열)

      1. pArr[ : 배열이군
      1. [3] : 요소가 3개군 -> 왼쪽해석
      1. int *pArr[3] : int형 주소를 가리키는 3개 포인터 변수를 갖는 배열이군

    int (*pArr)[3] (배열 포인터)

      1. (*pArr) : 포인터군
      1. [3] : 요소개 3개인 배열이군
      1. int (*pArr)[3] : 요소가 int 형이고 3개인 배열을 가리키는 포인터군

    int (*pFunc)() (함수 포인터)

      1. *pFunc : 포인터군
      1. () : 함수군
      1. int (*pFunc)() : int형 변수를 return 하는 함수 주소를 가리키는 포인터군
  • 포인터배열, 배열포인터, 함수포인터, 이중포인터

    포인터는 32 bit CPU 에서 4bytes다. 낚이지말자

  • 포인터 배열 돌발문제 )

char *ptr[] = {"red", "orange", "pink", "white", "blue", "brown", "black", "gray"};

/*
**ptr = r
ptr[1] = orange
ptr[1] + 3 = nge
*(*ptr + 1)+1) = r
*(*(ptr+2)+1)) = i
ptr[3] + 2 = ite
*/
  • 연습하자..

LED 연습

  • TOOLPATH -> 컴파일러 위치
  • cp $(TOPDIR)/$@ /tftpboot
    • @ : 실행하겠다는 문법

포인터의 주소

  • 포인터 변수의 주소를 저장하는 또다른 형태의 포인터 변수가 존재한다 ?
    • 이중 포인터 int **pp;

void

#include <stdio.h>

int main(){
	int a = 10;
	double b = 3.5;
	void *vp;
	
	vp = &a;
	printf("a : %d\n", *(int *)vp);
	vp = &b;
	printf("b : %.1f\n", *(double *)vp);
}
  • void는 모든 타입의 주소를 저장할 수 있다.
  • 간접 참조연산, 증감은 안됨 -> 몇 바이트 액세스할지 결정되지 않았기 때문
  • 증감크기 또는 액세스 하고 싶은 크기로 "Type Casting 해서 사용"

구조체

  • 얕은 복사와 깊은 복사

#include <stdlib.h>
#include <string.h>

typedef struct person_t
{
    char *name;
    int age;    
} Person;


void Normal_Copy_Test(void)
{
	Person src = { NULL, 20 };
    Person dest;
	
    src.name = malloc(4);
    strcpy(src.name, "JSH");
    
    dest = src; // (X)
    strcpy(dest.name, "AAA"); // (X)

    printf("Src[%s], Dest[%s] \n",
        src.name, dest.name);
}

void Deep_Copy_Test(void)
{
	Person dest, src = { NULL, 20 };
    
    src.name = malloc(4);
    strcpy(src.name, "JSH");
    
    dest.name = malloc(strlen(src.name) + 1);
    strcpy(dest.name, src.name);
    dest.age = src.age;

    strcpy(dest.name, "AAA");
  
    printf("Src[%s], Dest[%s] \n",
        src.name, dest.name);
}

void main(void)
{
    printf("========== Normal_Copy_Test ========== \n");
	Normal_Copy_Test(); // AAA AAA
	
	
	printf("\n\n\n========== Deep_Copy_Test ========== \n");
	Deep_Copy_Test(); // JSH AAA
}

Copy

profile
OnePunchLotto

0개의 댓글