경일 메타버스 20220429 4주차 5일 수업내용. C언어 문자열 함수 + 포인터 간략한 설명, 함수
https://docs.google.com/document/d/1pTQ2cg7jq36qksTc5IRbD86jXhDA6vpIgkhbzS9uyrk/edit
toupper 함수 : 헤더파일 <ctype.h>, 소문자를 대문자로 바꿔주는 함수.
strcpy 함수 : 헤더파일 <string.h>, strcpy(문자열 객체 포인터, “문자열” or 다른 문자열 객체 포인터), 문자열 객체에 문자열을 복사해 내용을 바꿔주는 함수.
null(’\0’) 종료가 되는 문자열만 받을 수 있다. 안된다면 다른 메모리에 침범. Undefined Behavior
Undefined Behavior : 표준에서 정의하지 않은 행동. 어떤 일이 일어날지 예상이 어려움. 프로그래머는 주의해야 함.
strcat 함수 : 헤더파일 <string.h>, strcat(문자열 객체 포인터, “문자열” or 다른 문자열 객체 포인터),
문자열 객체에 문자열을 뒤에 복사해 붙여주는 함수.
strlen 함수 : 헤더파일 <string.h>, strlen(문자열 객체 포인터), null문자를 제외하고, 문자열의 길이를 구해주는 함수.
typedef 기존타입 새타입 : 타입에 의미를 부여하고 이름을 정의한다.
strcmp 함수 : 헤더파일 <string.h>, strcmp(문자열 객체 포인터, “문자열” or 다른 문자열 객체 포인터), 두 문자열을 비교하여 아스키 코드와 길이 순으로 비교하여 상태를 리턴.
데이터를 메모리 주소값으로 해석. 메모리 주소를 값으로 갖는 객체.
포인터 초기화
NULL을 넣거나
다른 객체의 주소를 넣거나
Type Identifier
int p; ⇒ pointer to int
직접 참조(Direct Reference / Direct Access) : 메모리 주소에 직접 접근하는 것
num = 20;
간접 참조(Indirect Reference / Indirect Access) : 메모리 주소를 포인터를 통해서 접근
*p = 20;
Scope (범위) : 프로그램이 식별자를 찾을 수 있는 영역
주의 : C 언어는 안전하지 못한 언어 ⇒ 포인터의 사용에서 형식을 맞지 않게 넣지 않도록 조심할 것.
포인터는 중복 사용(적용) 가능
Potinter Type 크기는 얼마인가?
Address Operation : 주소 연산
배열 : a[b] ⇒ *(a + b);
주의 : 역참조 연산자와 증감 연산자를 결합할 때 연산 순서를 유의해야 한다.
void* p; // pointer to void(int, double, fuction, ~)
Deference X : 내가 가리키고 있는 타입이 뭔지도 모르는데 어떻게 해석?
Address Operation? : 가리키는 타입이 없기에 사용 불가
다만 어떤 주소든 담을 수 있기에, 주소 자체만을 사용할 때 유용하다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void Swap(int* a, int* b)
{
// a : 0x1234 -> 0xabcd
// b : 0x5678 -> 0x5780
int temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
char input[] = "A bird came down the walk";
// Pointer : 데이터를 메모리 주소값으로 해석
// Type* Identifier;
// int* p; => pointer to int
int a = 10; // a : 0x1234
int b = 20; // b : 0x5678
// a <-> b
Swap(&a, &b);
printf("%d %d", a, b);
int num = 10;
int* p2 = NULL;
int* p = #
int* * p3 = &p; // pointer to pointer to int
**p3 = 30;
int*** p4 = &p3; // pointer to pointer to pointer to int
***p4 = 50;
*p = 20;
// 왜? 포인터를 사용해야 하는가
// 메모리에 접근하는 방법은 2가지가 있다.
// 직접 참조(Direct Reference / Direct Access) : 메모리 주소에 직접 접근하는 것
// num = 20;
// 간접 참조(Indirect Reference / Indirect Access) : 메모리 주소를 포인터를 통해서 접근하는 것
// *p = 20;
a;
// Scope : 프로그램이 식별자를 찾을 수 있는 영역
// Block Scope => Local Variable
// File Scope => Global Variable
// Pointer Type 크기는 얼마인가?
// Pointer Type : 데이터를 메모리 주소값으로 해석한다.
// x86 : 4byte
// x64 : 8byte
// + - : 메모리 주소를 가리키고 있는 타입의 크기만큼 옮긴다.
// ++ / --
// Address Operation : 주소 연산
int arr[2] = { 10, 20 };
p = arr; // arr의 첫 번째 원소의 주소를 가리키게 된다.
p = p + 1; // &arr[1]
p = p - 1; // &arr[0]
++p;
--p;
p++;
p--;
char* pch; // pointer to character
pch + 1; // 1 바이트만큼 뒤로
pch - 1; // 1 바이트만큼 앞으로
// a[b] => *(a + b);
p = arr;
// 주의 : 역참조 연산자와 증감 연산자를 결합할 때 연산 순서를 유의해야 한다.
int num2 = *p++;
num2 = *++p;
num2 = ++(*p);
printf("\n%d", sizeof p);
// [1][2][3]
// p
int n = *p++; // n = 1
// *p : 역참조를 한 후
// p++ : 포인터의 주소값을 증가시킨다.
int n = *++p; // n = 3
// ++p : 포인터의 주소값을 증가시킨 후
// *p : 역참조한다.
int n = ++(*p); // n = 4
// *p : 역참조한 후 3
// ++ : 역참조한 값을 증가시킨다.
int sum(int x, int y)
{
return x + y;
}
void foo()
{
if (1)
{
// 반환 타입이 void인 경우에도 return문을 사용할 수 있으며
// 함수를 중간에 끝낼 때 사용한다.
return;
}
}
// strchr() : 문자열에서 특정 문자의 위치를 찾는 것
// 입력 : 문자열(const char*), 내가 찾을 문자(const char)
// 처리 : 입력된 문자열에서 그 문자가 나온 위치(메모리 주소)를 찾는다.
// 출력 : 문자의 위치 => 그 문자가 있는 메모리 주소값(char*)
// 1. 문자가 있는 경우 => 그 문자의 위치
// 2. 문자가 없는 경우 => NULL
// char* pos = strchr("Hello, 'l');
// "Hello"
// ↑
// 1. 문제 정의 => 입력, 처리, 출력. 문제를 충분히 해결할 수 있을 정도로 계속해서 작은 단위로 쪼개서 생각해야 함.
// 2. 작은 문제로 쪼갰다면 그 문제를 해결할 절차를 기술.
// 3. 문제를 해결하기 위해 어떤 데이터가 필요한가? => 즉, 어떤 데이터를 저장해야 하는가?
char* strchr(const char* str, const char ch)
{
while (*str != '\0')
{
if (*str == ch)
{
return (char*)str;
}
++str;
}
return NULL;
}```