[c] C 문자 배열 초기화
다음과 같은 방법으로 초기화 후 char 배열에 무엇이 있을지 잘 모르겠습니다.
1. char buf[10] = "";
2. char buf[10] = " ";
3.char buf[10] = "a";
경우 2, 나는 생각 buf[0]
해야한다 ' '
, buf[1]
해야한다 '\0'
, 그리고에서 buf[2]
에 buf[9]
임의의 콘텐츠 될 것입니다. 케이스 3의 경우 , 이어야하고 , ‘\ 0’ buf[0]
이어야하며 'a'
, to 는 임의의 콘텐츠가 될 것입니다.buf[1]
buf[2]
buf[9]
그 맞습니까?
그리고 사례 1의 경우 buf
? buf[0] == '\0'
과에서 buf[1]
하는 것은 buf[9]
임의의 콘텐츠 것인가?
답변
이것은 배열을 초기화하는 방법이 아니라 다음을위한 것입니다.
-
첫 번째 선언 :
char buf[10] = "";
다음과 같다
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
두 번째 선언 :
char buf[10] = " ";
다음과 같다
char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
세 번째 선언 :
char buf[10] = "a";
다음과 같다
char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
보시다시피 임의의 콘텐츠가 없습니다. 초기화 프로그램이 더 적 으면 나머지 배열은 0
. 이것은 배열이 함수 내에서 선언 된 경우에도 마찬가지입니다.
답변
편집 : OP (또는 편집자)는이 답변을 제공 한 후 원래 질문의 일부 작은 따옴표를 큰 따옴표로 자동 변경했습니다.
코드로 인해 컴파일러 오류가 발생합니다. 첫 번째 코드 조각 :
char buf[10] ; buf = ''
이중 불법입니다. 첫째, C에는 비어있는 char
. 다음과 같이 큰 따옴표를 사용하여 빈 문자열을 지정할 수 있습니다.
char* buf = "";
그러면 NUL
문자열에 대한 포인터가 제공됩니다 . 즉, 문자 만있는 단일 문자열입니다 NUL
. 그러나 그 안에 아무것도없는 작은 따옴표는 사용할 수 없습니다. 즉, 정의되지 않았습니다. NUL
문자 를 지정해야하는 경우 지정해야합니다.
char buf = '\0';
백 슬래시는 문자와 구별하기 위해 필요합니다 '0'
.
char buf = 0;
똑같은 일을 해내지만, 전자는 좀 덜 애매 모호하다고 생각합니다.
둘째, 배열을 정의한 후에는 초기화 할 수 없습니다.
char buf[10];
배열을 선언하고 정의합니다. 배열 식별자 buf
는 이제 메모리의 주소이며 buf
할당을 통해 포인트 위치를 변경할 수 없습니다 . 그래서
buf = // anything on RHS
불법입니다. 두 번째 및 세 번째 코드 조각은 이러한 이유로 불법입니다.
배열을 초기화하려면 정의 할 때 수행해야합니다.
char buf [10] = ' ';
첫 번째 문자는 공백 '\040'
이고 나머지는 NUL
, 즉 '\0'
. 이니셜 라이저를 사용하여 배열을 선언하고 정의하면 지정된 초기 값이있는 배열 요소 (있는 경우)를 지나는 배열 요소가 자동으로 0
. “무작위 콘텐츠”는 없습니다.
다음과 같이 배열을 선언하고 정의하지만 초기화하지 않는 경우 :
char buf [10];
모든 요소에 무작위 콘텐츠가 있습니다.
답변
-
이들은 동등합니다
char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
이들은 동등합니다
char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
이들은 동등합니다
char buf[10] = "a"; char buf[10] = {'a'}; char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
답변
C11 표준 초안 n1570 6.7.9 초기화의 관련 부분은 다음과 같습니다.
14 문자 유형의 배열은 문자열 리터럴 또는 UTF-8 문자열 리터럴로 초기화 될 수 있으며 선택적으로 중괄호로 묶입니다. 문자열 리터럴의 연속 바이트 (공간이 있거나 배열 크기를 알 수없는 경우 종료 널 문자 포함)는 배열의 요소를 초기화합니다.
과
(21) 이있는 경우 요소 또는 집합의 구성원, 또는이보다 중괄호로 둘러싸인 목록에 적은 이니셜 배열의 요소가보다 알려진 크기의 배열을 초기화하는 데 사용되는 문자열 리터럴 적은 문자, 집합의 나머지 정적 저장 기간 이있는 객체와 동일하게 암시 적으로 초기화 됩니다.
따라서 공간이 충분 하면 ‘\ 0’이 추가 되고 나머지 문자는 static char c;
함수 내에서 a가 초기화되는 값 으로 초기화됩니다.
드디어,
10 자동 저장 기간이있는 개체가 명시 적으로 초기화되지 않은 경우 해당 값은 확정되지 않습니다. 정적 또는 스레드 저장 기간이 있는 객체가 명시 적으로 초기화되지 않은 경우 :
[-]
- 산술 유형이 있으면 0 (양수 또는 부호 없음)으로 초기화됩니다.
[-]
따라서 char
산술 유형이기 때문에 배열의 나머지 부분도 0으로 초기화됩니다.
답변
흥미롭게도 배열이 a struct
또는의 멤버 인 경우 프로그램에서 언제든지 어떤 방식 으로든 배열을 초기화 할 수 있습니다 union
.
예제 프로그램 :
#include <stdio.h>
struct ccont
{
char array[32];
};
struct icont
{
int array[32];
};
int main()
{
int cnt;
char carray[32] = { 'A', 66, 6*11+1 }; // 'A', 'B', 'C', '\0', '\0', ...
int iarray[32] = { 67, 42, 25 };
struct ccont cc = { 0 };
struct icont ic = { 0 };
/* these don't work
carray = { [0]=1 }; // expected expression before '{' token
carray = { [0 ... 31]=1 }; // (likewise)
carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *'
iarray = (int[32]){ 1 }; // (likewise, but s/char/int/g)
*/
// but these perfectly work...
cc = (struct ccont){ .array='a' }; // 'a', '\0', '\0', '\0', ...
// the following is a gcc extension,
cc = (struct ccont){ .array={ [0 ... 2]='a' } }; // 'a', 'a', 'a', '\0', '\0', ...
ic = (struct icont){ .array={ 42,67 } }; // 42, 67, 0, 0, 0, ...
// index ranges can overlap, the latter override the former
// (no compiler warning with -Wall -Wextra)
ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ...
for (cnt=0; cnt<5; cnt++)
printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);
return 0;
}
답변
확실하지 않지만 일반적으로 배열을 “”로 초기화합니다.이 경우 문자열의 null 끝에 대해 걱정할 필요가 없습니다.
main() {
void something(char[]);
char s[100] = "";
something(s);
printf("%s", s);
}
void something(char s[]) {
// ... do something, pass the output to s
// no need to add s[i] = '\0'; because all unused slot is already set to '\0'
}