기존에 문자열을 복사하려면 상당히 복잡하게 하였다.
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
int main() {
char name[100];
strcpy(name, "hi");
printf("%s", name);
return 0;
}
기존에 strcpy를 사용해 이런 형식으로 사용했을것이다.
C++는 기존 문자열 사용의 불편한점을 해결한 클래스가 존재한다.
바로 std::string이다
std::string
C++에서 문자열을 활용하기 위한 클래스형 문자열 타입
string헤더파일에 정의되어 있다.
std::string에는 문자열을 이용한 여러가지 동작을 할 수 있도록 여러 멤버함수가 정의되어 있다.
또한 문자열의 포인터를 자동으로 관리해주기 때문에 하나하나 포인터를 관리할 필요 없이 정적인 형태의 클래스 인스턴스로 활용할 수 있다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <string>
int main() {
std::string name = "hi";
return 0;
}
std:: 형태로 사용한다.
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <string>
int main() {
std::string name = "hi";
printf("%s", name.c_str());
return 0;
}
출력은 이런 형태로 하면 된다.
기존 printf("%s", name); 형태로 실행을 해보면 이상한 값이뜬다.
이것은 std::string name이 포인터로 할당되서 그렇다.
C++를 사용하면 이렇게도 가능하다.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
int main() {
std::string name = "hi";
std::cout << name;
return 0;
}
#include <iostream>을 하고 std::cout << 변수 이름을 하면 된다.
하지만 printf로만 출력 하겠다.
std::cout은 따로 입문으로 적어서 복습할 생각이다.
std::string::compare(...)
strcmp 라는 함수와 동일한 일을 하는 멤버 함수
현재 문자열 클래스의 문자열과 파라미터로 입력받은 문자열을 비교하여
같다면 0
현재 문자열 클래스가 우선순위가 높다면 1
파라미터로 받은 문자열 우선순위가 높다면 2를 리턴한다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
int main() {
std::string str1 = "apple";
std::string str2 = "banana";
if (str1.compare(str2) == 0) {
printf("두 문자열은 같습니다");
}
else {
printf("두 문자열은 다릅니다");
}
return 0;
}
이러면 else 구문에 있는 '두 문자열은 다릅니다' 가 출력이 된다.
둘 다 apple이면 같다고 나온다. 한 번 banana를 apple로 바꿔보고 실행해보자.
std
std를 계속 썼는데 std는 뭐냐하면 standard라는 뜻이다.
namespace
프로그래머끼리 같은 이름을 사용하지 않도록 이름들을 구분해주는 역할을 하는 개념
이 namespace는 Java에서는 package로 불리며, C#에서는 동일하게 namespace라고 부른다.
사용법은 간단하다
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
namespace lee {
void foo() {
printf("혜성씨가 만든 함수 foo");
}
}
namespace dang {
void foo() {
printf("당혜성이 만든 함수 foo");
}
}
int main() {
lee::foo();
dang::foo();
return 0;
}
그리고 선언과 몸체를 분리할 수 있다.
예시 코드
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
namespace lee {
void foo();
}
namespace dang {
void foo();
}
int main() {
lee::foo();
dang::foo();
return 0;
}
void lee::foo() {
printf("혜성씨가 만든 foo");
}
void dang::foo() {
printf("혜성씨가 만든 foo");
}
사실 namespace를 공부할때 사용하고 딱히 사용할 일이 없다.
사용 하는 사람들은 엔드급개발자 정도이다.
근데 요즘도 깃허브 같은걸로 다 충돌 하는지 안하는지 보면서 하기 때문에 굳이굳이이다.
그리고 std는 생략이 가능하다.
위에 include 밑에 using namespace std; 를 적어주면 된다.
class도 가능하다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
namespace lee {
void foo();
class marine {
public:
void printinfo(int i, const char* c) {
}
};
}
int main() {
return 0;
}
lee::marine::marine() {
}
void lee::marine::printinfo(int i, const char* c) {
}
대충 이렇게 사용한다.
레퍼런스(Reference) 타입
파라미터를 받을때 타입 오른쪽에 &(앰퍼샌드)기호를 이용하게 되면 파라미터를 레퍼런스 타입으로 받을 수 있게 된다.
이 레퍼런스 타입은 파라미터로 일어나는 값 복사를 막아주어 실행할 수 있는 장점이 있다.
값을 스왑해 주는 코드가 있다.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
void swap(int a, int b) {
int temp;
temp = a;
a = b;
b = temp;
}
int main() {
int v1 = 100;
int v2 = 200;
swap(v1, v2);
printf("v1:%d\nv2:%d", v1, v2);
return 0;
}
이렇게 실행하면 값이 안바뀐다 라고 전에 강의에 있다.
이것을 해결하기 위한것은 포인터를 넣어 사용할 수 있고,
다른 하나는 &를 넣어서 한다.
&를 넣으면 *를 안적어도 된다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
void swap(int& a, int& b) {
int temp;
temp = a;
a = b;
b = temp;
}
int main() {
int v1 = 100;
int v2 = 200;
swap(v1, v2);
printf("v1:%d\nv2:%d", v1, v2);
return 0;
}
변수를 그대로 가져온다고 보면 된다.
std::string도 똗같다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
void swap(std::string& a, std::string & b) {
std::string temp;
temp = a;
a = b;
b = temp;
}
int main() {
std::string v1 = "hi";
std::string v2 = "bye";
swap(v1, v2);
printf("v1:%s\nv2:%s", v1.c_str(), v2.c_str());
return 0;
}
이렇게 사용하면 값복사를 최소로 사용하게 된다.
파라미터를 사용하면 값을 복사해서 넣어주는건데, 이게 사소해 보이지만 문자열이 길어질수록 값이 나오는데 길어질 수 있다.
상당히 중요한 내용이다.
만약 10만번을 실행한다고 하자.
파라미터에 &를 사용하지 않은 코드
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
#include <ctime>
using namespace std;
void swap(std::string a, std::string b) {
std::string temp;
temp = a;
a = b;
b = temp;
}
int main() {
std::string v1 = "hi";
std::string v2 = "bye";
float start = clock();
for (int i = 0; i < 100000; i++) {
swap(v1, v2);
}
float end = clock();
float time = (end - start) / CLOCKS_PER_SEC;
printf("경과 시간%f", time);
//printf("v1:%s\nv2:%s", v1.c_str(), v2.c_str());
return 0;
}
파라미터에 &붙인 코드
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string>
#include <ctime>
using namespace std;
void swap(std::string& a, std::string& b) {
std::string temp;
temp = a;
a = b;
b = temp;
}
int main() {
std::string v1 = "hi";
std::string v2 = "bye";
float start = clock();
for (int i = 0; i < 100000; i++) {
swap(v1, v2);
}
float end = clock();
float time = (end - start) / CLOCKS_PER_SEC;
printf("경과 시간%f", time);
//printf("v1:%s\nv2:%s", v1.c_str(), v2.c_str());
return 0;
}
아마 둘이 실행하면 실행하면 시간이 꽤나 많이 차이가 난다.
'C언어 공부' 카테고리의 다른 글
C++ 심화 - 5 STL 핵심 / Generic 이라고 불릴 수 있는 개념 (0) | 2025.03.20 |
---|---|
C++ 언어 심화 - 4 const / static / extern (0) | 2025.03.20 |
C++ 심화 - 2 프로그램의 실행구조 / Bitwise / 순수 가상함수 (0) | 2025.03.19 |
C++ 심화 - 1 여러개의 헤더와 소스 (0) | 2025.03.17 |
C++ 기초 - 6 열거형 - 가독성을 위한 타입 (0) | 2025.03.16 |