#include <iostream>
using namespace std;
int main()
{
double wages[3] = { 10000.0, 20000.0, 30000.0 };
short stacks[3] = { 3,2,1 };
//배열의 주소를 알아내는 두 가지 방법
double* pw = wages; //배열 이름 = 첫번째 원소의 주소
short* ps = &stacks[0]; //배열 원소에 주소 연산자 사용
cout << "pw = " << pw << ", pw= " << *pw << endl;
pw = pw + 1;
cout << "pw 포인터에 1을 더함: " << endl;
cout << "pw= " << pw << ", *pw = " << *pw << endl << endl;
cout << "ps= " << ps << ", *ps= " << *ps << "\n";
ps = ps + 1;
cout << "ps 포인터에 1을 더함 : " << endl;
cout << "ps= " << ps << ", *ps= " << *ps << "\n\n";
cout << "배열 표기로 두 원소에 접근 \n";
cout << "stacks[0] = " << stacks[0] << ", stacks[1]= " << stacks[1] << endl;
cout << "포인터 표기로 두 원소에 접근 \n";
cout << "*stacks= " << *stacks << ", *(stacks+1)= " << *(stacks + 1) << endl << endl;
cout << sizeof(wages) << " = wages 배열의 크기 \n";
cout << sizeof(pw) << " = pw 포인터의 크기\n";
return 0;
}
-> double* pw = wages; : wages=&wages[0]; 배열의 이름은 배열의 첫번째 원소의 주소를 의미
cout << "pw = " << pw << ", pw= " << *pw << endl;
pw = pw + 1;
cout << "pw 포인터에 1을 더함: " << endl;
cout << "pw= " << pw << ", *pw = " << *pw << endl << endl;
: pw: 8바이트 증가 / *pw : 다음 원소
cout << "ps= " << ps << ", *ps= " << *ps << "\n";
ps = ps + 1;
cout << "ps 포인터에 1을 더함 : " << endl;
cout << "ps= " << ps << ", *ps= " << *ps << "\n\n";
: ps: 2바이트 증가 / *ps : 다음 원소
cout << "배열 표기로 두 원소에 접근 \n";
cout << "stacks[0] = " << stacks[0] << ", stacks[1]= " << stacks[1] << endl;
cout << "포인터 표기로 두 원소에 접근 \n";
cout << "*stacks= " << *stacks << ", *(stacks+1)= " << *(stacks + 1) << endl << endl;
: 배열[0] = * pointer_name / 배열[1] = *(pointer_name +1)
cout << sizeof(wages) << " = wages 배열의 크기 \n";
cout << sizeof(pw) << " = pw 포인터의 크기\n";
: 24= 배열의 크기 / 4=포인터의 크기[배열의 지시하더라도 항상 같은 크기이다]
- arrayname[i] = *(arrayname +i)
- pointername[i] = *(pointername +i)
- 배열의 주소
- 배열의 이름 vs 배열의 주소
- 배열의 이름 : 배열의 첫 번째 원소의 주소
- 배열의 주소 : 전체 배열의 주소
- short tell[10]; : 20바이트 배열
- &tell : 전체 배열의 주소
- short(*)20 : short형 20바이트 배열
- short(*pas)[20] = &tell : pas는 20바이트 배열을 가리킨다.
- short *pas[20] : pas는 short를 가리키는 20개의 포인터 배열
- 배열의 이름 vs 배열의 주소
포인터와 문자열
// ptrstr.cpp -- 문자열을 지시하는 포인터의 사용
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring> // strlen(), strcpy()를 선언
int main()
{
using namespace std;
char animal[20] = "bear"; // animal에 bear가 들어 있다
const char* bird = "wren"; // bird에 문자열의 주소가 들어 있다
char* ps; // 초기화되지 않았다
cout << animal << " and "; // bear를 출력한다
cout << bird << "\n"; // wren을 출력한다
// cout << ps << "\n"; // 쓰레기 출력하거나 먹통이 될 수도 있다
cout << "동물의 종류를 입력하십시오: ";
cin >> animal; // 입력이 20문자 이내여야 한다
// cin >> ps; 절대로 해서는 안 될 엄청난 실수이다
// ps가 대입된 공간을 지시하고 있지 않다
ps = animal; // ps를 문자열을 지시하도록 설정한다
cout << ps << "s!\n"; // 맞다, animal을 사용하는 것과 동등
cout << "strcpy() 사용 전:\n";
cout << (int*)animal << ": " << animal << endl;
cout << (int*)ps << ": " << ps << endl;
ps = new char[strlen(animal) + 1]; // 새 메모리를 할당한다
strcpy(ps, animal); // 새 메모리에 문자열을 복사한다
cout << "strcpy() 사용 후:\n";
cout << (int*)animal << ": " << animal << endl;
cout << (int*)ps << ": " << ps << endl;
delete[] ps;
return 0;
}
-> strcpy 함수는 2017부터 unsafe 함수로 사용불가
-> strcpy_s 함수는 ( A, 버퍼의 크기, B)꼴로 버퍼의 크기를 정해줘야 한다.
-> strcpy 함수를 사용하려면 #define _CRT_SECURE_NO_WARNINGS을 해줘야 한다.
- C스타일 문자열과 cstring 라이브러리 사용
- 문자열을 배열에 저장하는 함수
- strcpy()
- strncpy()
- 세 번째 매개변수에 복사할 최대 문자수 지정
- 마지막 문자열엔 \0을 추가해야한다.
- 연산자는 배열을 초기화 할때만 사용한다.
- 문자열을 배열에 저장하는 함수
- C++의 string형을 사용하는 게 바람직하다.
#include <iostream>
using namespace std;
struct inflatable //구조체 템플릿
{
char name[20];
float volume;
double price;
};
int main()
{
inflatable* ps = new inflatable; //구조체를 위한 메모리 대입
cout << "모형풍선의 이름을 입력하십시오 : ";
cin.get(ps->name, 20); //멤버에 접근하는 제2 방법; 간접 멤버 접근연산자 사용
cout << "부피를 세제곱 피트 단위로 입력하십시오.: ";
cin >> (*ps).volume; //멤버에 접근하는 제1 방법 : 멤버 접근 연산자 사용
cout << "가격을 달러 단위로 입력하십시오: $";
cin >> ps->price;
cout << "이름: " << (*ps).name << endl; //제 1 방법
cout << "부피: " << ps->volume << " cubic feet\n"; //제2 방법
cout << "가격: $" << ps->price << endl; //제2 방법
delete ps; //구조체가 사용한 메모리 해제
return 0;
}
-> 구조체 생성 -> 구조체 멤버에 접근 (접근방법 2가지 -> 구조체변수.멤버변수 / 구조체포인터->멤버변수)
구조체와 포인터
struct things
{
int good;
int bad;
};
things grubnose={3, 453};
things* pt=&grubnose;
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
char* getname(void); //함수원형
int main()
{
char* name; //포인터를 만들지만 메모리는 대입하지 않는다.
name = getname(); //문자열의 주소를 name에 대입한다
cout << (int*)name << ": " << name << "\n";
delete[] name; //메모리 해제
name = getname(); //해제한 메모리 사용
cout << (int*)name << ": " << name << "\n";
delete[] name; //메모리 다시 해제
return 0;
}
char* getname() //새 문자열을 가리키는 포인터 리턴하는 함수
{
char temp[80]; //임시 배열
cout << "이름을 입력하십시오: ";
cin >> temp;
char* pn = new char[strlen(temp) + 1]; //널 문자 포함해 +1 크기
strcpy(pn, temp); //문자열을 더 작은 공간을 복사한다.
return pn; //함수가 종료될 때 임시 배열인 temp은 소멸
}
- 대입하는 방법에 따른 메모리 분류
- 자동공간
- 호출 -> 종료
- 스택에 저장
- LIFO
- 정적공간
- 실행되는 동안 지속
- 외부에서 변수 선언
- static 변수 선언
- 동적공간
- 분리된 메모리
- 힙에 저장
- delete 안하면 메모리 누수
- 자동공간
'Programming > C++ 2' 카테고리의 다른 글
[C++ 연습문제] 4장. 복합데이터형 (1) (0) | 2021.04.07 |
---|---|
[C++ 실습] 4장-09. 변수형의 조합 (0) | 2021.04.06 |
[C++ 실습] 4장-07. 포인터와 메모리 해제 (0) | 2021.04.04 |
[C++ 실습] 4장-04. 구조체 (0) | 2021.04.04 |
[C++ 실습] 4장-03. String 클래스 (0) | 2021.04.04 |