INTRO

1주차에는 패스트캠퍼스 컴퓨터공학 올인원 패키지에의 c언어의 기본내용을 설명하는 강의를 듣고 정리를 하였다.

포인터

포인터의 개념

  1. 변수는 그 자체로 자신의 자료형에 맞는 값을 저장 한다.
  2. 포인터(*) 변수는 특이한 변수로, 메모리 주소를 저장한다.
  3. 포인터는 특정한 변수 자체가 존재하는 메모리 주소의 값을 가진다.
  4. 따라서 아래 예저에서 a를 이영해서 5라는 값을 찾을 수 있지만, 포인터 변수인 b를 이용해서도 5라는 값에 접근할 수 있다.

image.png

포인터 관련 연산자

- 주소연산자 : &
    - 변수 앞에 붙어서 변수의 메모리 시작 주소값을 구한다.
- 포인터 : *
    - 포인터 변수를 선언할 때 사용한다.
- 간접 참조 연산자 : *
    - 선언된 포인터 변수가 가리키는 변수를 구한다.

※ int *b와 *b 비교

  • int *b = &a : 선언할때 사용하는 *는 포인터 변수임을 알려주기위한 목적이다.

  • *b : 여기서 *는 포인터변수 b가 가르키는 주소의 값을 의미한다.(즉, *b에는 주소값 a가 들어 있는데, a 변수에는 5가 들어 있으므로 5를 의미)

    #include<stdio.h>
    int main(void) {
      int a = 5;
        int *b = &a;
        printf("%d\n",*b); // 5
        return 0;
    }
    

배열에서의 포인터

int형은 4바이트를 가지므로 아래와 같이 메모리 주소 한칸을 1바이트로 표현하면 4칸을 차지하게된다. 배열을 이용하면 동일한 자료형을 연속적인 공간에 위치 시키므로. 배열의 원소 끼리는 주소값 4가 차이 나게 된다. 또한 배열의 이름 그 자체가 배열의 메모리 시작값이다.
image.png

#include<stdio.h>

int main(void) {
    int a[] = {1,2,3,4,5,6,7,8,9,10}
    int i;
      for(i = 0; i < 10; i++){
        printf("%d\n",&a[i]);
    }
      return 0;
}

image.png

포인터의 강력한 기능

  1. 포인터는 컴퓨터 시스템의 특정 메모리에 바로 접근할 수 있다.

  2. 기존에 존재하던 중요한 메모리 영역에 접근하지 않도록 해야한다.

  3. 아래의 코드는 특정 메모리에 바로접근해서 0으로 바꾸는 코드 이므로 매우 위험한 코드이다.

    int *a = 0X33484735;
    *a = 0;
  4. 포인터는 다중으로 사용할 수 있다.
    ~c
    int main ( void) {
    int a = 5;
    int b = &a;
    int *
    c = &b; //포인터의 포인터 변수
    printf("%d\n",**C);
    return 0;
    }




## C언어의 문자와 문자열

### Goal
- c언어에서 문자를 처리하는 방법을 이해한다.
- 문자와 버퍼의 관계를 이해한다.
- 문자열을 다루는 방법에 대해서 학습한다.
- 다양한 문자열 관련 함수를 익히고 활용한다.
### 아스키코드

c 프로그램의 문자는 아스키 코드를 따른다. 아스키 코드는 0~127중의 1바이트로 구성되며 주요 문자를 출력하도록 해준다.
      아스키코드

0 ~ 9 : 48 ~ 57
A : 65
a : 97



### 버퍼의 개념

문자열을 처리할 때 버퍼의 개념이 많이 사용된다. 버퍼란 임시적으로 특정한 데이터를 저장하기 위한 목적으로 사용된다. C프로그램은 기본적으로 사용자가 의도하지 않아도 자동으로 버퍼를 이용해 입출력을 처리한다.


### 문자열의 개념
1. 문자열은 말 그대로 문자들의 배열이다.
2. 문자열은 컴퓨터 구조상에서 마지막에 NULL값을 포함한다.


### 문자열과 포인터
1. 문자열 형태로 포인터를 사용하면 포인터에 특정한 문자열의 주소를 넣게 된다.
2. 다음 코드는 "Hello World" 문자열을 읽기 전용으로 메모리 공간에 넣은 뒤에 그 위치를 처리한다.
3. 이러한 문자열을 문자열 리터럴 이라고 한다. 컴파일러가 알아서 메모리 주소를 결정한다.

~~~c
#include<stdio.h>
char *a = "HELLO WORLD";
printf("%s\n",a);
return 0;

gets vs scanf

scanf함수는 공백을 만날 때 까지 입력 받지만, gets는 공백을 포함하여 한 줄을 입력 받는다.

#include<stdio.h>
int main(){
  char a[100];
  gets(a);
  printf("%s\n");
  return 0;
}

문자열 처리를 위한 다양한 함수

  • c언어의 문자열 처리와 관련해서는 기본적인 문자열 함수를 알고 있는것이 좋다.
  • 나중에 C++을 이용하면 더욱 간편하고 다양한 함수를 사용할 수 있다.
  • c언어에서는 string.h 라이브러리에 포함되어 있다.
strlen() : 문자열의 길이를 반환한다.
strcmp() : 문자열 1이 문자열 2보다 사전적으로 앞에 있으면 -1 뒤에 있으면 1반환
strcpy() : 문자열을 복사한다.
strcat() : 문자열에 1에 문자열 2를 더한다.
strstr() : 문자열 1에 문자열 2가 어떻게 포함되어 있는지를 반환한다.
  1. strlen()
    #include<stdio.h>
    int main(void) {
       char a[20] = "HELLO";
       printf("%d",strlen(a));
     return 0;
    }
  1. strcmp()
    #include<stdio.h>
    int main() {
     char a[20] = "AAA";
     char b[20] = "BBB";
       printf("%d",strcmp(a,b));
       return 0;
    }
  1. strcpy()
#include<stdio.h>
int main(){
    int a[20] = "My Name";
      int b[20] = "Alvin";
      strcpy(a,b);
      printf("%s",a);
      return 0;
}
  1. strcat()

    #include <stdio.h>
    int main() {
     int a[20] = "My Name";
       int b[20] = "Alvin";
       strcat(a,b);
       printf("%s",a);
       return 0;
    }
  2. strstr()
    찾은 문자열의 주소 값 자체를 반환하므로 단순히 출력하도록 하면, 찾은 이후 모든 문자열이 반환된다.

#include<stdio.h>
int main() {
    char a[20] = "I Like you";
    char b[20] = 'Like';
      printf("%s",strstr(a,b)); //Like you 출력
      return 0;
}

컴퓨터가 변수를 처리하는 방법

프로그램 메모리 주소

  1. 컴퓨터에서 프로그램이 실행되기 위해서는 프로그램이 메모리에 적재 되야 한다.
  2. 따라서, 프로그램의 크기릉 충당할 수 있을 만큼의 메모리 공간이 있어야 한다.
  3. 일반적인 컴퓨터 운영체제는 메모리 공간을 네가지로 구분하여 관리한다.

[ 코드영역 | 데이터영역 | 힙 영역 | 스택영역 ]
소스코드 전역변수 동적 할당 변수 지역변수
정적변수 매개변수

전역변수

  1. Global Variable(전역변수)란 프로그램의 어디서든 접근 가능한 변수를 의미
  2. main함수가 실행되기도 전에 프로그램이 시작과 동시에 메모리에 할당된다.
  3. 프로그램의 크기가 커질 수록 전역변수로 인해 프로그램이 복잡해질 수 있다
#include<stdio.h>
int a = 5 // Global Variable
void changeValue() {
  a = 10
}
int main() {
  printf("%d",a); // 5
  changeValue();
  printf("%d",a) // 10
  return 0;
}

지역변수

  1. 지역변수란 프로그램에서 특정한 블록에서만 접근할 수 있는 변수를 의미
  2. 함수가 실행될 때마다 메모리에 할당되어 함수가 종료되면 메모리에서 해제
  3. 메모리의 스택영역에 기록된다.
#include<stdio.h>
int main() {
  int a = 5 // local Variable
  printf("%d",a); // 5
  if(1) {
   int a = 10; //local variable
 }
  return 0;
}

정적변수

  1. 특정한 블록에서만 접근할 수 있는 변수
  2. 프로그램이 실행될 때 메모리에 할당되어 프로그램이 종료되면 메모리에서 해제
  3. 메모리의 데이터 영역에 적재
#include <stdio.h>
void process() {
  static int  = 5;
  a = a + 1;
  printf("%d",a);
}
int main() {
  process();
  process();
  return 0;
}
~~`



### 레지스터 변수

1. 메인 메모리 대신 cpu의 레지스터를 사용하는 변수이다.
2. 레지스터는 매우 한정되어 있으므로 실제로 레지스터에서  처리될 지는 장담할 수 없다.


~~~c
#include<stdio.h>
int main() {

 register int a = 10, i;
 for(i = 0; i < a; i++ ) {
    printf("%d",i);
  }
 return 0;
}

함수의 매개변수가 처리될 때

  1. 함수를 호출할 때 함수에 필요한 데이터를 매개변수로 전달한다.
  2. 전달 방식은 값에 의한 전달방식과, 참조에 의한 전달방식이 있다.
  3. 값에 의한 전달방식은 단지 값을 전달하므로 함수 내에서 변수가 새롭게 생성된다.
  4. 참조에 의한 전달방식은 주소를 전달하므로 원래의 변수 자체에 접근할 수 있다.

z