programing

끈이 미쳐가고 있어요 제가 좀 더 여유를 주지 않으면요여기서 무슨 일이 일어나고 있는지 설명해 줄 사람?

closeapi 2023. 11. 7. 20:53
반응형

끈이 미쳐가고 있어요 제가 좀 더 여유를 주지 않으면요여기서 무슨 일이 일어나고 있는지 설명해 줄 사람?

먼저, 저는 C/C++에 처음입니다. 저는 원래 PHP 개발자이기 때문에 변수를 마음대로 남용하도록 길러집니다.

C는 엄격한 나라이고, 컴파일러들은 나를 여기서 별로 좋아하지 않아요. 나는 일을 처리하기 위해 규칙을 어기는 것에 익숙합니다.

어쨌든, 이건 제 간단한 암호입니다.

char IP[15] = "192.168.2.1";
char separator[2] = "||";   

puts( separator );

출력:

||192.168.2.1

하지만 만약 내가 정의를 바꾼다면,separator대상:

char separator[3] = "||";

원하는 출력을 얻을 수 있습니다.

||

그럼 왜 제가 그 남자에게 여유 공간을 줘야 했단 말인가요? 그 남자가 자기 앞에 있는 남자와 잠자리를 같이 하지 않는 걸까요?

그 이유는 당신이 null-terminated 문자열을 얻을 수 있기 때문입니다.separator길이는 2로 강제됩니다.

항상 null 터미네이터에 추가 문자를 할당해야 합니다.길이의 문자열일 경우N당신이 필요합니다N+1성격.

이 요구 사항을 위반하면 null-terminated 문자열이 필요한 모든 코드(puts()함수 포함)에서 정의되지 않은 동작이 발생합니다.

특정 길이를 강요하지 않는 것이 최선의 방법입니다.

char separator[] = "||";

정확한 크기의 배열을 할당합니다.

C의 문자열은 NUL-종료됩니다.즉, 두 문자로 구성된 문자열에 3바이트(문자의 경우 2개, 문자열의 끝을 나타내는 0바이트의 경우 3개)가 필요합니다.

예제에서는 배열 크기를 생략할 수 있으며 컴파일러는 올바른 양의 스토리지를 할당합니다.

char IP[] = "192.168.2.1";
char separator[] = "||";

마지막으로, C가 아닌 C++로 코딩을 하고 있다면 사용하는 것이 좋습니다.std::string.

어쨌든 C++를 사용하는 경우 C 문자열 대신 std::string 클래스를 사용하는 것이 좋습니다. 특히 스크립트 언어 배경이 있는 사용자의 경우 훨씬 쉽고 오류가 발생하기 쉬운 IMHO입니다.

각 문자열 끝에 숨겨진 nul 문자 '\0'이 있습니다.당신은 그것을 위해 공간을 남겨야 합니다.

네가 한다면.

char seperator[] = "||";    

2사이즈가 아닌 3사이즈의 끈을 받으실 수 있습니다.

C에서 문자열은 null로 종료되기 때문입니다(끝은 0바이트로 표시됨).).구분자를 두 문자의 배열로 선언하고 두 문자에 모두 0이 아닌 값을 지정하면 종단자가 없습니다!그러므로 당신이puts배열은 거의 모든 것이 끝에 부착될 수 있습니다(whatever는 배열의 끝을 지나 메모리에 저장됩니다). 이 경우에는 다음과 같습니다.IP배열).

편집: 다음 내용이 올바르지 않습니다.아래 댓글을 참고하세요.

배열 길이를 3으로 만들면 여분의 바이트에 0이 들어 있어서 문자열이 종료됩니다.그러나 값이 초기화되지 않은 경우에는 실제로 무엇이든 포함할 수 있으므로 이러한 동작에 의존할 수 없습니다.

C에서 문자열은 특수로 끝납니다.'\0'문자, 그래서 구분 문자 리터럴"||"사실 한 글자가 더 깁니다.puts기능은 마주칠 때까지 모든 문자를 인쇄합니다.'\0'- IP 문자열 뒤에 하나씩 입력합니다.

C에서 문자열은 끝에 (보이지 않는) null 바이트를 포함합니다.그 null 바이트를 계산해야 합니다.

char ip[15] = "1.2.3.4";

위의 코드에서,ip15자를 위한 충분한 공간이 있습니다. 14자의 "일반 문자"와 null 바이트.너무 짧습니다: 그래야 합니다.char ip[16] = "1.2.3.4";

ip[0] == '1';
ip[1] == '.';
/* ... */
ip[6] == '4';
ip[7] == '\0';

지금까지 아무도 그것을 지적하지 않았기 때문에.이와 같이 변수를 선언하면 문자열이 자동으로 null로 종료되므로 배열 크기를 어슬렁거리지 않아도 됩니다.

const char* IP = "192.168.2.1"; 
const char* seperator = "||";

하지만 이 문자열들을 바꿀 생각은 없으리라 생각합니다.

그러나 이미 언급했듯이 C++에서 안전한 방법은 std::string 클래스를 사용하는 것입니다.

C "String"은 항상 NULL로 끝나지만 문자 구분 기호[2] = "||"로 적으면 문자열에 지정하지 않습니다.그리고 puts는 \0을 찾을 때까지 ned에서 이 \0을 예상합니다. 여기서 IP 주소의 끝에서 찾을 수 있는 위치를 볼 수 있습니다.지역 변수가 스택에 배치되는 방식을 확인할 수 있을 만큼 흥미롭습니다.

행:char seperator[2] = "||"; 해당 문자 배열의 길이(끝에 null 포함)가 3이므로 정의되지 않은 동작을 얻을 수 있습니다.

그리고 위의 코드를 어떤 컴파일러로 컴파일했습니까?제가 g++로 컴파일을 했는데 위 줄을 오류로 표시하였습니다.

C\C++의 문자열은 null로 종료됩니다. 즉, 끝에 숨겨진 0이 있습니다.

따라서 구분 문자열은 다음과 같습니다.

{'|', '|', '\0'} = "||"

언급URL : https://stackoverflow.com/questions/5882772/string-going-crazy-if-i-dont-give-it-a-little-extra-room-can-anyone-explain-wh

반응형