저는 오피스 문자열에 대한 총결산을 원합니다.
38930 단어 문자열
1. str* 시리즈 손글씨 코드
a. 끝부분'\0'처리에 유의하십시오.
b. 반드시 입력에 대해 유효성 판단을 해야 한다. 단언을 많이 하면 된다.int Strlen(const char* str) {
assert(str != NULL);
const char* tmp = str;
while (*tmp != '\0') {
++tmp;
}
return tmp - str;
}
char* Strcpy(char* dst, const char* src) {
assert(dst != NULL && src != NULL);
char* tmp = dst;
while (*src != '\0') {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
char* Strncpy(char* dst, const char* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* tmp = dst;
for (; len > 0 && *src != '\0'; --len) {
*tmp++ = *src++;
}
for (; len > 0; --len) {
*tmp ++ = '\0';
}
return dst;
}
char* Strcat(char* dst, const char* src) {
assert(dst != NULL && src != NULL);
char* tmp = dst;
while (*tmp != '\0') {
++tmp;
}
while (*src != '\0') {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
char* Strncat(char* dst, const char* src, int len) {
assert(dst != NULL && src != NULL && n >= 0);
char* tmp = dst;
while (*tmp != '\0') {
++tmp;
}
for (; len > 0 && *src != '\0'; --len) {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
int Strcmp(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
for (; *str1 == *str2; ++str1, ++str2) {
if (*str1 == '\0') {
return 0;
}
}
if (*(unsigned char*)str1 < *(unsigned char*)str2) {
return -1;
} else {
return 1;
}
}
int Strncmp(const char* str1, const char* str2, int len) {
assert(str1 != NULL && str2 != NULL && len >= 0);
for (; len > 0; ++str1, ++str2) {
if (*str1 != *str2) {
return ((*(unsigned char*)str1) < (*(unsigned char*)str2) ? -1 : 1);
} else if (*str1 == '\0') {
return 0;
}
}
return 0;
}
char* Strchr(const char* str, int c) {
assert(str != NULL);
const char* tmp = str;
const char ch = (const char)c;
for (; *tmp != ch; ++tmp) {
if (*tmp == '\0') {
return NULL;
}
}
return (char*)tmp;
}
char* Strstr(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
if (*str2 == '\0') return str1;
const char* tmp1 = str1;
const char* tmp2 = str2;
int len1 = Strlen(str1);
int len2 = Strlen(str2);
int i = 0;
for (tmp1 = str1; i <= len1 - len2 && *tmp1 != '\0'; ++tmp1, ++i) {
if (*tmp1 != *tmp2)
continue;
const char* cur1 = tmp1;
const char* cur2 = tmp2;
while (*cur1 == *cur2) {
++cur1;
++cur2;
if (*cur2 == '\0') {
return (char*)tmp1;
}
}
}
return NULL;
}
2. mem* 시리즈 손글씨 코드
반드시 입력에 대해 유효성 판단을 해야 하며, 단언을 많이 쓰면 된다void* Memchr(const void* src, int c, int len) {
assert(src != NULL && len >= 0);
const unsigned char ch = c;
const unsigned char* tmp = (const unsigned char*)src;
for (; len > 0; --len, ++tmp) {
if (*tmp == ch) {
return (void*)tmp;
}
}
return NULL;
}
int Memcmp(const void* s1, const void* s2, int len) {
assert(s1 != NULL && s2 != NULL);
const unsigned char* tmp1 = (const unsigned char*)s1;
const unsigned char* tmp2 = (const unsigned char*)s2;
for (; len > 0; --len, tmp1++, tmp2++) {
if (*tmp1 != *tmp2) {
return ((*tmp1 < *tmp2) ? -1 : 1);
}
}
return 0;
}
void* Memcpy(void* dst, const void* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* dstTmp = (char*)dst;
const char* srcTmp = (const char*)src;
for (; len > 0; --len, ++dstTmp, ++srcTmp) {
*dstTmp = *srcTmp;
}
return dst;
}
void* Memmove(void* dst, const void* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* dstTmp = (char*)dst;
const char* srcTmp = (const char*)src;
if (dstTmp > srcTmp && dstTmp < srcTmp + len) {
for (srcTmp += n, dstTmp += n; len > 0 ; --len, --srcTmp, --dstTmp) {
*dstTmp = *srcTmp;
}
} else {
for (; len > 0; --len, ++srcTmp, ++dstTmp) {
*dstTmp = *srcTmp;
}
}
return dst;
}
3. atoi 함수
atoi 함수의 실현 class Solution {
public:
int atoi(const char *str) {
assert(str != NULL);
const char* curr = str;
const int maxRange = 10; int tmp = 0;
int num = 0;
while(isspace(*curr)) {
++curr;
}
const char* start = nullptr;
char sign;
if (*curr == '-' || *curr == '+') {
sign = *curr;
++curr;
start = curr;
} else {
start = curr;
}
while (isdigit(*curr)) {
tmp = num;
num = num * 10 + (*curr - '0');
++curr;
}
int len = 0;
if (!isdigit(*curr)) {
len = curr - start;
}
--curr;
if (len > maxRange || num < num - *curr) {
if (sign == '-') {
return INT_MIN;
} else {
return INT_MAX;
}
}
if (sign == '-') num = -num;
return num;
}
};
4.std::string 구현
c++ std::string의 간편한 실현 class Mystring {
public:
Mystring() : data_(new char[1]) {
*data = '\0';
}
explicit Mystring(const char* str) : data_(new char[strlen(str) + 1]) {
strcpy(data_, str);
}
explicit Mystring(const Mystring& str) : data_(new char[str.size() + 1]) {
strcpy(data_, str.c_str());
}
~Mystring() {
delete[] data_;
}
// , copy and swap ,
Mystring& operator=(const Mystring& str) {
Mystring tmp(str);
swap(tmp);
return *this;
}
// , copy and swap ,
Mystring& operator=(Mystring& str) {
swap(str);
return *this;
}
int size() const {
return (int)strlen(data_);
}
const char* c_str() const {
return data_;
}
void swap(Mystring& str) {
std::swap(data_, str.data_);
}
private:
char* data_;
};
a. Mystring 클래스는 내장형 int와 같이 변수를 정의할 수 있고 복사할 수 있으며 값을 부여할 수 있습니다
b. Mystring은 함수 매개 변수와 반환 값 유형으로 사용할 수 있습니다.
c. Mystring은 표준 라이브러리 컨테이너의 요소 유형, 즉vector/list/deque의valuetype
d. RAII를 이용하여 자원을 정확하게 관리하고 구조 함수에서만 new char[]를 호출하며 분석 함수에서만 delete[]를 호출한다.
e. 재부팅 연산자 사용 copy and swap 수법
5. 스트로 대수 계산
남-수
class Solution {
public:
string multiply(string num1, string num2) {
if (num1.size() == 0 || num2.size() == 0) return "";
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
vector<int> result(num1.size() + num2.size(), 0);
int count = 0;
for (int i = 0; i < num1.size(); ++i) {
for (int j = 0; j < num2.size(); ++j) {
result.at(i+j) += (num1.at(i) - '0') * (num2.at(j) - '0');
}
}
for (int i = 0; i < result.size(); ++i) {
int tmp = result.at(i) + count;
result.at(i) = tmp % 10;
count = tmp / 10;
}
int zeroPos = 0;
for (zeroPos = result.size() - 1; zeroPos >= 0; --zeroPos) {
if (result.at(zeroPos) != 0) break;
}
result.erase(result.begin() + zeroPos + 1, result.end());
reverse(result.begin(), result.end());
string res(result.size(), '0');
for (int i = 0; i < result.size(); ++i) {
res.at(i) += result.at(i);
}
if (res == "") {
return "0";
} else {
return res;
}
}
};
6. 왜 char*p = "hello"라는 표현을 금지합니까?
C언어를 공부하는 학우들은 반드시char*p="hello"와 같은 문법을 본 적이 있다. 지금 내가 하고 싶은 말은 절대로 이렇게 쓰지 말라는 것이다.int main() {
char* p1 = "hello";
char* p2 = "hello";
char p3[] = "hello";
char p4[] = "hello";
fprintf(stdout, "%p:%p
", p1, p2);
fprintf(stdout, "%p:%p
", p3, p4);
return 0;
}
프로그램 결과: p1은 p2이고 p3은 p4가 아닙니다
p1은 p2와 같다. "Hello"는 문자열 상수로 전역 const 구역에 위치하고 있다. 첫째, 상수 const이다. 둘째, 수정될 수 없다. 전역적이다. 즉, 모든 "Hello"를 가리키는 바늘의 주소 값은 똑같다.
p3은 p4:p3과 p4가 아닌 문자 그룹으로 창고에 위치하고 문자 그룹의 문자는 수정할 수 있습니다
요약: char* p1 = "hello";
char p3[] = "hello";
p1: 가리키는 내용은 수정할 수 없음 (전역const), p1 바늘은 수정할 수 있음 (지향을 변경할 수 있음)
p3: 가리키는 요소는 수정할 수 있음(일반 수조), p3는 수정할 수 없음(수조 이름이 지침일 때 수조의 첫 번째 주소를 표시하므로 수정할 수 없음)
char*p = "hello"로 돌아가기
앞에서 우리가 설명한 바와 같이 p가 가리키는 내용은 수정할 수 없다. 즉, p는 const를 가리키는 지침이다.const char* p1 = "hello";
왜 const를 넣었을까요?
왜냐하면char*p="hello"는 실제constchar*은밀히char*로 변환하기 때문에 모든 악의 변환입니다. 코드를 보십시오. char* p1 = "this is wrong";
char* p2 = "hello world";
strcpy(p1, p2);
컴파일링이 통과되었는데, 실행하시겠습니까?하하
앞에서 말했듯이 p1은 실제로constchar*입니다. 지금 p1을 통해const를 수정하려면 반드시 코어 dump가 필요합니다.
그런데 우리가 이렇게 쓰면? const char* p1 = "this is wrong";
const char* p2 = "hello world";
strcpy(p1, p2);
컴파일 오류!!!(주: g++ - Wall 컴파일을 사용합니다)
요약:char* p1 = "this is wrong"; // const , p1
const char* p1 = "this is right"; // const const , p1
위에서 strcpy 함수를 예로 사용한 이상strcpy 문제를 다시 말하다
만약 상술한 문제를 모두 이해했다면 다음과 같은 코드이다.int main() {
char dst[] = "this is right";
const char* src = "hello world";
strcpy(dst, src);
fprintf(stdout, "%s", dst);
return 0;
}
운행은 모두 좋지만, 내가 말하고 싶은 것은strcpy와 같은 함수를 사용하지 말라는 것이다.
우리는 C 언어 표준 라이브러리에 strcpy,strcat,strcmp가 있다는 것을 안다
C 표준 라이브러리에도 다음과 같은 함수가 있다:strncpy,strncat,strncmp
strcpy strncpy를 예로 들다
strcpy는 src의'\0'을 만나야만 복사를 끝냅니다. dst의 공간이 src를 수용할 수 있든 없든 간에 버퍼가 넘치기 쉽습니다.××공격이 쇄도하다
그래서 strcpy에 대응하는'안전'버전이 생겼습니다. strncpy, strncpy는 원래 strcpy의 불안정성을 해결하려고 했지만 그 의미는 정말 사람을 아프게 합니다.
strncpy는 src의 전 n 바이트만 복제합니다. 만약 src의 전 n 바이트에 종료자 '\0' 이 포함되지 않는다면 문제가 발생합니다. src의 종료자를 복제하지 않습니다.어이가 없네.
일반적으로 strncpy를 사용하는 방법은 다음과 같습니다.strncpy(dst, src, strlen(dst));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini
사용 소프트웨어는 Houdini16.5입니다
배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
int Strlen(const char* str) {
assert(str != NULL);
const char* tmp = str;
while (*tmp != '\0') {
++tmp;
}
return tmp - str;
}
char* Strcpy(char* dst, const char* src) {
assert(dst != NULL && src != NULL);
char* tmp = dst;
while (*src != '\0') {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
char* Strncpy(char* dst, const char* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* tmp = dst;
for (; len > 0 && *src != '\0'; --len) {
*tmp++ = *src++;
}
for (; len > 0; --len) {
*tmp ++ = '\0';
}
return dst;
}
char* Strcat(char* dst, const char* src) {
assert(dst != NULL && src != NULL);
char* tmp = dst;
while (*tmp != '\0') {
++tmp;
}
while (*src != '\0') {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
char* Strncat(char* dst, const char* src, int len) {
assert(dst != NULL && src != NULL && n >= 0);
char* tmp = dst;
while (*tmp != '\0') {
++tmp;
}
for (; len > 0 && *src != '\0'; --len) {
*tmp++ = *src++;
}
*tmp = '\0';
return dst;
}
int Strcmp(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
for (; *str1 == *str2; ++str1, ++str2) {
if (*str1 == '\0') {
return 0;
}
}
if (*(unsigned char*)str1 < *(unsigned char*)str2) {
return -1;
} else {
return 1;
}
}
int Strncmp(const char* str1, const char* str2, int len) {
assert(str1 != NULL && str2 != NULL && len >= 0);
for (; len > 0; ++str1, ++str2) {
if (*str1 != *str2) {
return ((*(unsigned char*)str1) < (*(unsigned char*)str2) ? -1 : 1);
} else if (*str1 == '\0') {
return 0;
}
}
return 0;
}
char* Strchr(const char* str, int c) {
assert(str != NULL);
const char* tmp = str;
const char ch = (const char)c;
for (; *tmp != ch; ++tmp) {
if (*tmp == '\0') {
return NULL;
}
}
return (char*)tmp;
}
char* Strstr(const char* str1, const char* str2) {
assert(str1 != NULL && str2 != NULL);
if (*str2 == '\0') return str1;
const char* tmp1 = str1;
const char* tmp2 = str2;
int len1 = Strlen(str1);
int len2 = Strlen(str2);
int i = 0;
for (tmp1 = str1; i <= len1 - len2 && *tmp1 != '\0'; ++tmp1, ++i) {
if (*tmp1 != *tmp2)
continue;
const char* cur1 = tmp1;
const char* cur2 = tmp2;
while (*cur1 == *cur2) {
++cur1;
++cur2;
if (*cur2 == '\0') {
return (char*)tmp1;
}
}
}
return NULL;
}
반드시 입력에 대해 유효성 판단을 해야 하며, 단언을 많이 쓰면 된다
void* Memchr(const void* src, int c, int len) {
assert(src != NULL && len >= 0);
const unsigned char ch = c;
const unsigned char* tmp = (const unsigned char*)src;
for (; len > 0; --len, ++tmp) {
if (*tmp == ch) {
return (void*)tmp;
}
}
return NULL;
}
int Memcmp(const void* s1, const void* s2, int len) {
assert(s1 != NULL && s2 != NULL);
const unsigned char* tmp1 = (const unsigned char*)s1;
const unsigned char* tmp2 = (const unsigned char*)s2;
for (; len > 0; --len, tmp1++, tmp2++) {
if (*tmp1 != *tmp2) {
return ((*tmp1 < *tmp2) ? -1 : 1);
}
}
return 0;
}
void* Memcpy(void* dst, const void* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* dstTmp = (char*)dst;
const char* srcTmp = (const char*)src;
for (; len > 0; --len, ++dstTmp, ++srcTmp) {
*dstTmp = *srcTmp;
}
return dst;
}
void* Memmove(void* dst, const void* src, int len) {
assert(dst != NULL && src != NULL && len >= 0);
char* dstTmp = (char*)dst;
const char* srcTmp = (const char*)src;
if (dstTmp > srcTmp && dstTmp < srcTmp + len) {
for (srcTmp += n, dstTmp += n; len > 0 ; --len, --srcTmp, --dstTmp) {
*dstTmp = *srcTmp;
}
} else {
for (; len > 0; --len, ++srcTmp, ++dstTmp) {
*dstTmp = *srcTmp;
}
}
return dst;
}
3. atoi 함수
atoi 함수의 실현 class Solution {
public:
int atoi(const char *str) {
assert(str != NULL);
const char* curr = str;
const int maxRange = 10; int tmp = 0;
int num = 0;
while(isspace(*curr)) {
++curr;
}
const char* start = nullptr;
char sign;
if (*curr == '-' || *curr == '+') {
sign = *curr;
++curr;
start = curr;
} else {
start = curr;
}
while (isdigit(*curr)) {
tmp = num;
num = num * 10 + (*curr - '0');
++curr;
}
int len = 0;
if (!isdigit(*curr)) {
len = curr - start;
}
--curr;
if (len > maxRange || num < num - *curr) {
if (sign == '-') {
return INT_MIN;
} else {
return INT_MAX;
}
}
if (sign == '-') num = -num;
return num;
}
};
4.std::string 구현
c++ std::string의 간편한 실현 class Mystring {
public:
Mystring() : data_(new char[1]) {
*data = '\0';
}
explicit Mystring(const char* str) : data_(new char[strlen(str) + 1]) {
strcpy(data_, str);
}
explicit Mystring(const Mystring& str) : data_(new char[str.size() + 1]) {
strcpy(data_, str.c_str());
}
~Mystring() {
delete[] data_;
}
// , copy and swap ,
Mystring& operator=(const Mystring& str) {
Mystring tmp(str);
swap(tmp);
return *this;
}
// , copy and swap ,
Mystring& operator=(Mystring& str) {
swap(str);
return *this;
}
int size() const {
return (int)strlen(data_);
}
const char* c_str() const {
return data_;
}
void swap(Mystring& str) {
std::swap(data_, str.data_);
}
private:
char* data_;
};
a. Mystring 클래스는 내장형 int와 같이 변수를 정의할 수 있고 복사할 수 있으며 값을 부여할 수 있습니다
b. Mystring은 함수 매개 변수와 반환 값 유형으로 사용할 수 있습니다.
c. Mystring은 표준 라이브러리 컨테이너의 요소 유형, 즉vector/list/deque의valuetype
d. RAII를 이용하여 자원을 정확하게 관리하고 구조 함수에서만 new char[]를 호출하며 분석 함수에서만 delete[]를 호출한다.
e. 재부팅 연산자 사용 copy and swap 수법
5. 스트로 대수 계산
남-수
class Solution {
public:
string multiply(string num1, string num2) {
if (num1.size() == 0 || num2.size() == 0) return "";
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
vector<int> result(num1.size() + num2.size(), 0);
int count = 0;
for (int i = 0; i < num1.size(); ++i) {
for (int j = 0; j < num2.size(); ++j) {
result.at(i+j) += (num1.at(i) - '0') * (num2.at(j) - '0');
}
}
for (int i = 0; i < result.size(); ++i) {
int tmp = result.at(i) + count;
result.at(i) = tmp % 10;
count = tmp / 10;
}
int zeroPos = 0;
for (zeroPos = result.size() - 1; zeroPos >= 0; --zeroPos) {
if (result.at(zeroPos) != 0) break;
}
result.erase(result.begin() + zeroPos + 1, result.end());
reverse(result.begin(), result.end());
string res(result.size(), '0');
for (int i = 0; i < result.size(); ++i) {
res.at(i) += result.at(i);
}
if (res == "") {
return "0";
} else {
return res;
}
}
};
6. 왜 char*p = "hello"라는 표현을 금지합니까?
C언어를 공부하는 학우들은 반드시char*p="hello"와 같은 문법을 본 적이 있다. 지금 내가 하고 싶은 말은 절대로 이렇게 쓰지 말라는 것이다.int main() {
char* p1 = "hello";
char* p2 = "hello";
char p3[] = "hello";
char p4[] = "hello";
fprintf(stdout, "%p:%p
", p1, p2);
fprintf(stdout, "%p:%p
", p3, p4);
return 0;
}
프로그램 결과: p1은 p2이고 p3은 p4가 아닙니다
p1은 p2와 같다. "Hello"는 문자열 상수로 전역 const 구역에 위치하고 있다. 첫째, 상수 const이다. 둘째, 수정될 수 없다. 전역적이다. 즉, 모든 "Hello"를 가리키는 바늘의 주소 값은 똑같다.
p3은 p4:p3과 p4가 아닌 문자 그룹으로 창고에 위치하고 문자 그룹의 문자는 수정할 수 있습니다
요약: char* p1 = "hello";
char p3[] = "hello";
p1: 가리키는 내용은 수정할 수 없음 (전역const), p1 바늘은 수정할 수 있음 (지향을 변경할 수 있음)
p3: 가리키는 요소는 수정할 수 있음(일반 수조), p3는 수정할 수 없음(수조 이름이 지침일 때 수조의 첫 번째 주소를 표시하므로 수정할 수 없음)
char*p = "hello"로 돌아가기
앞에서 우리가 설명한 바와 같이 p가 가리키는 내용은 수정할 수 없다. 즉, p는 const를 가리키는 지침이다.const char* p1 = "hello";
왜 const를 넣었을까요?
왜냐하면char*p="hello"는 실제constchar*은밀히char*로 변환하기 때문에 모든 악의 변환입니다. 코드를 보십시오. char* p1 = "this is wrong";
char* p2 = "hello world";
strcpy(p1, p2);
컴파일링이 통과되었는데, 실행하시겠습니까?하하
앞에서 말했듯이 p1은 실제로constchar*입니다. 지금 p1을 통해const를 수정하려면 반드시 코어 dump가 필요합니다.
그런데 우리가 이렇게 쓰면? const char* p1 = "this is wrong";
const char* p2 = "hello world";
strcpy(p1, p2);
컴파일 오류!!!(주: g++ - Wall 컴파일을 사용합니다)
요약:char* p1 = "this is wrong"; // const , p1
const char* p1 = "this is right"; // const const , p1
위에서 strcpy 함수를 예로 사용한 이상strcpy 문제를 다시 말하다
만약 상술한 문제를 모두 이해했다면 다음과 같은 코드이다.int main() {
char dst[] = "this is right";
const char* src = "hello world";
strcpy(dst, src);
fprintf(stdout, "%s", dst);
return 0;
}
운행은 모두 좋지만, 내가 말하고 싶은 것은strcpy와 같은 함수를 사용하지 말라는 것이다.
우리는 C 언어 표준 라이브러리에 strcpy,strcat,strcmp가 있다는 것을 안다
C 표준 라이브러리에도 다음과 같은 함수가 있다:strncpy,strncat,strncmp
strcpy strncpy를 예로 들다
strcpy는 src의'\0'을 만나야만 복사를 끝냅니다. dst의 공간이 src를 수용할 수 있든 없든 간에 버퍼가 넘치기 쉽습니다.××공격이 쇄도하다
그래서 strcpy에 대응하는'안전'버전이 생겼습니다. strncpy, strncpy는 원래 strcpy의 불안정성을 해결하려고 했지만 그 의미는 정말 사람을 아프게 합니다.
strncpy는 src의 전 n 바이트만 복제합니다. 만약 src의 전 n 바이트에 종료자 '\0' 이 포함되지 않는다면 문제가 발생합니다. src의 종료자를 복제하지 않습니다.어이가 없네.
일반적으로 strncpy를 사용하는 방법은 다음과 같습니다.strncpy(dst, src, strlen(dst));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini
사용 소프트웨어는 Houdini16.5입니다
배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
class Solution {
public:
int atoi(const char *str) {
assert(str != NULL);
const char* curr = str;
const int maxRange = 10; int tmp = 0;
int num = 0;
while(isspace(*curr)) {
++curr;
}
const char* start = nullptr;
char sign;
if (*curr == '-' || *curr == '+') {
sign = *curr;
++curr;
start = curr;
} else {
start = curr;
}
while (isdigit(*curr)) {
tmp = num;
num = num * 10 + (*curr - '0');
++curr;
}
int len = 0;
if (!isdigit(*curr)) {
len = curr - start;
}
--curr;
if (len > maxRange || num < num - *curr) {
if (sign == '-') {
return INT_MIN;
} else {
return INT_MAX;
}
}
if (sign == '-') num = -num;
return num;
}
};
c++ std::string의 간편한 실현
class Mystring {
public:
Mystring() : data_(new char[1]) {
*data = '\0';
}
explicit Mystring(const char* str) : data_(new char[strlen(str) + 1]) {
strcpy(data_, str);
}
explicit Mystring(const Mystring& str) : data_(new char[str.size() + 1]) {
strcpy(data_, str.c_str());
}
~Mystring() {
delete[] data_;
}
// , copy and swap ,
Mystring& operator=(const Mystring& str) {
Mystring tmp(str);
swap(tmp);
return *this;
}
// , copy and swap ,
Mystring& operator=(Mystring& str) {
swap(str);
return *this;
}
int size() const {
return (int)strlen(data_);
}
const char* c_str() const {
return data_;
}
void swap(Mystring& str) {
std::swap(data_, str.data_);
}
private:
char* data_;
};
a. Mystring 클래스는 내장형 int와 같이 변수를 정의할 수 있고 복사할 수 있으며 값을 부여할 수 있습니다
b. Mystring은 함수 매개 변수와 반환 값 유형으로 사용할 수 있습니다.
c. Mystring은 표준 라이브러리 컨테이너의 요소 유형, 즉vector/list/deque의valuetype
d. RAII를 이용하여 자원을 정확하게 관리하고 구조 함수에서만 new char[]를 호출하며 분석 함수에서만 delete[]를 호출한다.
e. 재부팅 연산자 사용 copy and swap 수법
5. 스트로 대수 계산
남-수
class Solution {
public:
string multiply(string num1, string num2) {
if (num1.size() == 0 || num2.size() == 0) return "";
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
vector<int> result(num1.size() + num2.size(), 0);
int count = 0;
for (int i = 0; i < num1.size(); ++i) {
for (int j = 0; j < num2.size(); ++j) {
result.at(i+j) += (num1.at(i) - '0') * (num2.at(j) - '0');
}
}
for (int i = 0; i < result.size(); ++i) {
int tmp = result.at(i) + count;
result.at(i) = tmp % 10;
count = tmp / 10;
}
int zeroPos = 0;
for (zeroPos = result.size() - 1; zeroPos >= 0; --zeroPos) {
if (result.at(zeroPos) != 0) break;
}
result.erase(result.begin() + zeroPos + 1, result.end());
reverse(result.begin(), result.end());
string res(result.size(), '0');
for (int i = 0; i < result.size(); ++i) {
res.at(i) += result.at(i);
}
if (res == "") {
return "0";
} else {
return res;
}
}
};
6. 왜 char*p = "hello"라는 표현을 금지합니까?
C언어를 공부하는 학우들은 반드시char*p="hello"와 같은 문법을 본 적이 있다. 지금 내가 하고 싶은 말은 절대로 이렇게 쓰지 말라는 것이다.int main() {
char* p1 = "hello";
char* p2 = "hello";
char p3[] = "hello";
char p4[] = "hello";
fprintf(stdout, "%p:%p
", p1, p2);
fprintf(stdout, "%p:%p
", p3, p4);
return 0;
}
프로그램 결과: p1은 p2이고 p3은 p4가 아닙니다
p1은 p2와 같다. "Hello"는 문자열 상수로 전역 const 구역에 위치하고 있다. 첫째, 상수 const이다. 둘째, 수정될 수 없다. 전역적이다. 즉, 모든 "Hello"를 가리키는 바늘의 주소 값은 똑같다.
p3은 p4:p3과 p4가 아닌 문자 그룹으로 창고에 위치하고 문자 그룹의 문자는 수정할 수 있습니다
요약: char* p1 = "hello";
char p3[] = "hello";
p1: 가리키는 내용은 수정할 수 없음 (전역const), p1 바늘은 수정할 수 있음 (지향을 변경할 수 있음)
p3: 가리키는 요소는 수정할 수 있음(일반 수조), p3는 수정할 수 없음(수조 이름이 지침일 때 수조의 첫 번째 주소를 표시하므로 수정할 수 없음)
char*p = "hello"로 돌아가기
앞에서 우리가 설명한 바와 같이 p가 가리키는 내용은 수정할 수 없다. 즉, p는 const를 가리키는 지침이다.const char* p1 = "hello";
왜 const를 넣었을까요?
왜냐하면char*p="hello"는 실제constchar*은밀히char*로 변환하기 때문에 모든 악의 변환입니다. 코드를 보십시오. char* p1 = "this is wrong";
char* p2 = "hello world";
strcpy(p1, p2);
컴파일링이 통과되었는데, 실행하시겠습니까?하하
앞에서 말했듯이 p1은 실제로constchar*입니다. 지금 p1을 통해const를 수정하려면 반드시 코어 dump가 필요합니다.
그런데 우리가 이렇게 쓰면? const char* p1 = "this is wrong";
const char* p2 = "hello world";
strcpy(p1, p2);
컴파일 오류!!!(주: g++ - Wall 컴파일을 사용합니다)
요약:char* p1 = "this is wrong"; // const , p1
const char* p1 = "this is right"; // const const , p1
위에서 strcpy 함수를 예로 사용한 이상strcpy 문제를 다시 말하다
만약 상술한 문제를 모두 이해했다면 다음과 같은 코드이다.int main() {
char dst[] = "this is right";
const char* src = "hello world";
strcpy(dst, src);
fprintf(stdout, "%s", dst);
return 0;
}
운행은 모두 좋지만, 내가 말하고 싶은 것은strcpy와 같은 함수를 사용하지 말라는 것이다.
우리는 C 언어 표준 라이브러리에 strcpy,strcat,strcmp가 있다는 것을 안다
C 표준 라이브러리에도 다음과 같은 함수가 있다:strncpy,strncat,strncmp
strcpy strncpy를 예로 들다
strcpy는 src의'\0'을 만나야만 복사를 끝냅니다. dst의 공간이 src를 수용할 수 있든 없든 간에 버퍼가 넘치기 쉽습니다.××공격이 쇄도하다
그래서 strcpy에 대응하는'안전'버전이 생겼습니다. strncpy, strncpy는 원래 strcpy의 불안정성을 해결하려고 했지만 그 의미는 정말 사람을 아프게 합니다.
strncpy는 src의 전 n 바이트만 복제합니다. 만약 src의 전 n 바이트에 종료자 '\0' 이 포함되지 않는다면 문제가 발생합니다. src의 종료자를 복제하지 않습니다.어이가 없네.
일반적으로 strncpy를 사용하는 방법은 다음과 같습니다.strncpy(dst, src, strlen(dst));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini
사용 소프트웨어는 Houdini16.5입니다
배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
class Solution {
public:
string multiply(string num1, string num2) {
if (num1.size() == 0 || num2.size() == 0) return "";
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
vector<int> result(num1.size() + num2.size(), 0);
int count = 0;
for (int i = 0; i < num1.size(); ++i) {
for (int j = 0; j < num2.size(); ++j) {
result.at(i+j) += (num1.at(i) - '0') * (num2.at(j) - '0');
}
}
for (int i = 0; i < result.size(); ++i) {
int tmp = result.at(i) + count;
result.at(i) = tmp % 10;
count = tmp / 10;
}
int zeroPos = 0;
for (zeroPos = result.size() - 1; zeroPos >= 0; --zeroPos) {
if (result.at(zeroPos) != 0) break;
}
result.erase(result.begin() + zeroPos + 1, result.end());
reverse(result.begin(), result.end());
string res(result.size(), '0');
for (int i = 0; i < result.size(); ++i) {
res.at(i) += result.at(i);
}
if (res == "") {
return "0";
} else {
return res;
}
}
};
C언어를 공부하는 학우들은 반드시char*p="hello"와 같은 문법을 본 적이 있다. 지금 내가 하고 싶은 말은 절대로 이렇게 쓰지 말라는 것이다.
int main() {
char* p1 = "hello";
char* p2 = "hello";
char p3[] = "hello";
char p4[] = "hello";
fprintf(stdout, "%p:%p
", p1, p2);
fprintf(stdout, "%p:%p
", p3, p4);
return 0;
}
프로그램 결과: p1은 p2이고 p3은 p4가 아닙니다
p1은 p2와 같다. "Hello"는 문자열 상수로 전역 const 구역에 위치하고 있다. 첫째, 상수 const이다. 둘째, 수정될 수 없다. 전역적이다. 즉, 모든 "Hello"를 가리키는 바늘의 주소 값은 똑같다.
p3은 p4:p3과 p4가 아닌 문자 그룹으로 창고에 위치하고 문자 그룹의 문자는 수정할 수 있습니다
요약:
char* p1 = "hello";
char p3[] = "hello";
p1: 가리키는 내용은 수정할 수 없음 (전역const), p1 바늘은 수정할 수 있음 (지향을 변경할 수 있음)
p3: 가리키는 요소는 수정할 수 있음(일반 수조), p3는 수정할 수 없음(수조 이름이 지침일 때 수조의 첫 번째 주소를 표시하므로 수정할 수 없음)
char*p = "hello"로 돌아가기
앞에서 우리가 설명한 바와 같이 p가 가리키는 내용은 수정할 수 없다. 즉, p는 const를 가리키는 지침이다.
const char* p1 = "hello";
왜 const를 넣었을까요?
왜냐하면char*p="hello"는 실제constchar*은밀히char*로 변환하기 때문에 모든 악의 변환입니다. 코드를 보십시오.
char* p1 = "this is wrong";
char* p2 = "hello world";
strcpy(p1, p2);
컴파일링이 통과되었는데, 실행하시겠습니까?하하
앞에서 말했듯이 p1은 실제로constchar*입니다. 지금 p1을 통해const를 수정하려면 반드시 코어 dump가 필요합니다.
그런데 우리가 이렇게 쓰면?
const char* p1 = "this is wrong";
const char* p2 = "hello world";
strcpy(p1, p2);
컴파일 오류!!!(주: g++ - Wall 컴파일을 사용합니다)
요약:
char* p1 = "this is wrong"; // const , p1
const char* p1 = "this is right"; // const const , p1
위에서 strcpy 함수를 예로 사용한 이상strcpy 문제를 다시 말하다
만약 상술한 문제를 모두 이해했다면 다음과 같은 코드이다.
int main() {
char dst[] = "this is right";
const char* src = "hello world";
strcpy(dst, src);
fprintf(stdout, "%s", dst);
return 0;
}
운행은 모두 좋지만, 내가 말하고 싶은 것은strcpy와 같은 함수를 사용하지 말라는 것이다.
우리는 C 언어 표준 라이브러리에 strcpy,strcat,strcmp가 있다는 것을 안다
C 표준 라이브러리에도 다음과 같은 함수가 있다:strncpy,strncat,strncmp
strcpy strncpy를 예로 들다
strcpy는 src의'\0'을 만나야만 복사를 끝냅니다. dst의 공간이 src를 수용할 수 있든 없든 간에 버퍼가 넘치기 쉽습니다.××공격이 쇄도하다
그래서 strcpy에 대응하는'안전'버전이 생겼습니다. strncpy, strncpy는 원래 strcpy의 불안정성을 해결하려고 했지만 그 의미는 정말 사람을 아프게 합니다.
strncpy는 src의 전 n 바이트만 복제합니다. 만약 src의 전 n 바이트에 종료자 '\0' 이 포함되지 않는다면 문제가 발생합니다. src의 종료자를 복제하지 않습니다.어이가 없네.
일반적으로 strncpy를 사용하는 방법은 다음과 같습니다.
strncpy(dst, src, strlen(dst));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini사용 소프트웨어는 Houdini16.5입니다 배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.