배열 char에있는 요소의 수를 알기 위해 어떤 종류의 함수를 사용할 수 있습니까?
sizeof ()는 사용 가능한 “공백”의 수를 제공하므로 저에게는 작동하지 않습니다.
댓글
답변
strlen
를 원합니다.
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
댓글
- 답이 효과가 있었으면 " 수락 " 버튼 (확인 표시 모양)을 클릭하세요. 이렇게하면 다른 사람들이 솔루션이 작동했습니다.
- 몇 분 정도 기다려야했습니다.
- iv id =의 데이터가 만 작동한다는 점에 유의하세요. “4b03894 2c1 “>
는 ASCII 문자열을 포함하며 제대로 null로 종료됩니다. 또한 char[]
에 긴 문자열이 있고 null 종료를 추가하지 않고 더 짧은 문자열로 덮어 쓰면 이전 문자열의 크기가 표시됩니다.
답변
알아요 @NickGammon의 답변을 받으십시오. 그러나이 모든 작동 방식에 대해 좀 더 자세한 정보를 추가하고 싶습니다.
sizeof()
는 함수는 단어의 정상적인 의미에서 함수입니다. 전달하는 모든 것에 할당 된 메모리의 바이트 수를 제공하는 연산자입니다. 배열을 전달하면 배열이 사용할 수있는 바이트 수를 반환합니다. 배열에 대한 포인터를 전달하면 배열의 크기가 아니라 해당 포인터의 크기를 반환합니다. 정수 변수를 전달하면 해당 정수 변수가 사용하는 바이트 수를 반환합니다 (8 비트에서 2). AVR과 같은 시스템, Due와 같은 32 비트 시스템의 4).
몇 가지 예 :
char array[50] = "hello"; // sizeof(array) = 50. char *array_p = array; // sizeof(array_p) = 2 or 4 depending on architecture. char single = "a"; // sizeof(single) = 1. char string[] = "hello"; // sizeof(string) = 6 (5 letters plus \0) - it allocates the memory at compile time to fit the string
이제 strlen()
. sizeof()
와 정확히 어떻게 다른가요? 간단히 말해서 는 C 문자열의”NULL “종료 문자 인 \0
문자에 도달 할 때까지 문자 배열의 문자 수를 계산합니다. 이전의 예를 보되 대신 strlen을 사용합니다.
char array[50] = "hello"; // strlen(array) = 5. char *array_p = array; // strlen(array_p) = 5. char single = "a"; // strlen(single) = ERROR! strlen() doesn"t operate on single characters. char string[] = "hello"; // strlen(string) = 5.
항상 문자열의 문자 수를 반환하지만 다음을 포함하지 않는 것을 알 수 있습니다. 후행 \0
문자입니다.
가장 간단한 형식의 strlen()
함수는 다음과 같습니다.
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
기본적으로 문자열의 첫 번째 문자 (*p = data
)에서 시작하여 “\0
여부 (while (*p)
), 문자 수를 늘리고 (c++
) 다음 문자로 이동 문자열 (p++
).
프로그램에서 문자열을 반복하려면 strlen()
먼저 문자열의 문자 수를 얻은 다음 해당 값을 루프에서 사용합니다. strlen()
가 먼저 문자열을 반복하므로 두 번 반복하므로 약간 낭비입니다. strlen()
함수가 포인터 em를 사용하는 방법과 같이 종료 문자를 찾을 때까지 문자열의 각 문자를 단계별로 가장 잘 살펴 보는 방법을 배우는 것이 훨씬 더 효율적입니다. > 메모리를 통해 이동합니다. 또한 문자열 끝에 \0
문자가 있는지 확인하는 것이 얼마나 중요한지 확인할 수 있습니다. 그렇지 않으면 strlen()
언제 멈출 지 아십니까? 그들은 문자열의 길이를 알 수 없습니다 (sizeof()
는 전달되는 포인터의 크기를 반환하며 배열의 크기가 아닙니다). 따라서 그들은 어떤 종류의 수동 마커이며 C의 규칙은 \0
를 사용하는 것입니다.
Arduino의 print()
기능은 실제로 매우 비효율적으로 수행하십시오. 다음과 같은 작업을 수행하는 경우 :
char message[] = "Hello"; Serial.println(message);
실제로 정말 필요하지 않은 많은 작업을 수행합니다. 단계별로 :
- println (message) 호출
- write (message) 호출
- strlen (message)로 문자열 길이 가져 오기
- 그리고 write (message, length)를 호출합니다.
- 그런 다음 0에서 length-1까지 반복하여 메시지의 각 문자를 write ()에 차례로 보냅니다.
- 마지막으로 줄 바꿈에 대해
\r\n
를 인쇄합니다.
따라서 실제로 4 개의 함수를 중첩하여 끝나고 전체 문자열을 두 번 반복합니다. A 처리 시간을 낭비하는 방법의 전형적인 예입니다.write(message)
함수 (2 단계)에서 \0
문자를 찾기 위해 문자열을 반복하면 (2 단계) 최소 두 배 빠른 속도로 작동합니다. Good old Arduino …
코멘트
- Re “가장 단순한 형태의 strlen () 함수는 다음과 같을 수 있습니다.” 더 간단할까요?) 형식은 다음과 같습니다.
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 " 가장 간단하다고 말했습니다. ", " 가장 짧고 가장 컴팩트 한 "가 아닙니다. 이 형식은 더 작고 효율적이지만 OP (분명히 프로그래머가 아닌 )가 이해하기 훨씬 더 어렵습니다.
- 동의 🙂 또한 실수하기가 더 쉽습니다. . 그리고
\0
가 세그먼트에서 마지막으로 액세스 할 수있는 바이트이면*p++
에 오류가 발생합니다. 그러나int strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
는 이러한 문제를 방지합니다. - 사실
*p++
가 승리했습니다. '\0
가 세그먼트에서 마지막으로 액세스 가능한 바이트 인 경우에도 오류가 발생하지 않습니다.*p
부분은 마지막 바이트에 액세스합니다. ++ 부분은p
를 잘못된 주소로 설정합니다. 그러나 잘못된 주소는 ' 참조되지 않으므로 일반적인 시스템에서는 오류가 발생하지 않습니다. - 컴파일 타임 매크로입니다. '는 매크로 가 아니며 ' 연산자
입니다. b> (예 : " + " 및 "-"는 연산자). 그들은 전 처리기 시간에 수행되는 매크로보다 낮은 수준입니다. sizeof 연산자 를 참조하세요. 또한 C ++ 연산자
답변
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
댓글
- 질문을 제대로 읽었습니까?
- OP에서
sizeof
" 나에게 작동하지 않음 ' " 그런 다음 sizeof를 사용하는 것이 좋습니다. - 동일한 알 수없는 것을 사용할 때는 질문에 답할 수 없습니다.
char foo [100] = "bar";
-그게 무슨 뜻인가요? 답변을 원하십니까?