2009-07-29 4 views
4

내가 모두 보았다C : 문자열 배열을 올바르게 선언하는 방법?

const char* arr = {"foo", "bar"}; 

const char* arr[] = {"foo", "bar"}; 

올바른 일반적으로 표준 방법은 무엇입니까?

둘의 차이점은 무엇입니까?

const char**arr = {"foo", "bar"}; 

const char* arr[] = {"foo", "bar"}; 

const char* * const arr = {"foo", "bar"};  

const char* const * const arr = {"foo", "bar"}; 
,691 차이가 무엇

많은 질문에 사과 드리며, 더 나은 것을 이해하려고 노력 중입니다 ...

답변

2

...

const char* constValue = "foo"; 
constValue = "bar"; 
constValue[0] = 'x'; // will not work 

char* const constPtr = "foo"; 
constPtr = "bar"; // will not work 
constPtr[0] = 'x'; 

const char* const arr[] = { "foo", "bar", 0 }; // all const 

'const를 숯불 *의 CONST'는 종종 완벽하게 일정한 무언가를위한 최고의 솔루션입니다. 또 하나의 최적화는 로컬 범위에서 선언 된 경우이 정적을 만드는 것입니다. 0 ptr은 센티널 가치에 유용합니다.

10

올바른 간접 레벨이 없기 때문에 이것은 정확하지 않습니다.

const char* arr = {"foo", "bar"}; 

=이 누락되어 올바르지 않습니다. 그것은 함수 정의와 같은 것처럼 보입니다.

const char* arr[] {"foo", "bar"}; 

이것은 일반적으로 올바른 형식입니다.

const char* arr[] = { "foo", "bar" }; 

당신은 집계 이니셜 라이저에서 포인터를 초기화 할 수 없습니다

편집 (즉, {..., ..., ...}). 당신이 할 수있는 두

const char* str1 = "A string"; 

const char str2[] = "Another string"; 

하지만이 다르다.

문자열 리터럴에는 'array of n char'유형이 있으므로 포인터로 변환 할 수 있지만 초기화 목록은 실제로 배열이 아니며 배열을 초기화하는 방법 일뿐입니다.

+0

이전 코드에서는 다음과 같이 표시됩니다. const char ** arr = { "foo", "bar", NULL}; 그냥 괜찮아요. – dmckee

+2

이전 코드에서 수정이 필요하다고 제안한다면 const char *가 "foo"를 가리키는'arr' (const char **)을 초기화하고 여분의 초기화 도구를 버립니다. "경고 : 호환되지 않는 포인터 유형에서 초기화"및 "경고 : 스칼라 초기화 프로그램에서 초과 요소" –

+0

이것은 C 및 C++가 다른 한 영역입니다. C에서 문자열 리터럴은 "array N of char"가 아니라 "const char의 배열 N"유형입니다. –

0

일반적으로 가능한 경우 동적 메모리를 사용합니다. 나는 배열 타입을 가지고 싸우는 것보다 포인터에 대해 생각하는 것이 더 간단하다는 것을 안다.

//Allocate pointers for the strings 
char **c = (char**)malloc(maxnumofstrs*sizeof(int)); 
//allocate memory for each string 
for(int i = 0; i < maxnumofstrs; i++) 
{ 
    c[i] = (char*)malloc(maxwidth); 
} 
1

몇 가지 접근법이 있습니다. 가장 간단한과 같이, 문자의 배열의 배열을 선언하는 것입니다 :

char strs[N][M + 1]; // M is max length of each string 
... 
strcpy(strs[i], "foo"); 

문자열의 모든 메모리를 정적으로 할당되어 있지만, 배열의 각 문자열의 크기가 고정되어, 당신을 위해 크기가 가능한 가장 긴 문자열. 내부 조각화가 발생할 수 있습니다. 모든 문자열은 쓰기 가능합니다.

또 다른 방법은 숯불에 대한 포인터의 배열을 선언하는 것입니다 :

char *strs[N]; 
... 
strs[i] = malloc(strlen("bar") + 1); 
if (strs[i]) 
    strcpy(strs[i], "bar"); 

당신만큼 또는 배열 요구의 각 스트링 한 적은 메모리를 할당 할 수있는이 방법을, 필요한 경우 당신은 당신의 문자열의 크기를 조정할 수 있습니다 . 문자열 리터럴을 가리킬 수도 있지만 리터럴은 쓸 수 없다는 것을 기억하십시오. 즉, 당신은 같은 것을 할 수 없을 수 있습니다

strs[j] = "foo"; 
strs[j][0] = 'b'; // may not be allowed on string literal 
당신은 동적으로 전체 스매시 할당 할 수 있습니다

:

char **strs = malloc(sizeof *strs * N); 
for (i = 0; i < N; i++) 
    strs[i] = malloc(SIZE + 1); 

이 방법은 당신이뿐만 아니라 필요에 따라 각 문자열의 크기를 조정 할 수 있습니다,하지만 크기를 조정 캐릭터 라인의 수 이 경우 배열로 처리되는 경우에도 strs는 이 아니며 배열 유형이이 아닙니다.

malloc()과 관련된 모범 사례는 C와 C++에서 서로 다릅니다. C에서는 malloc()의 결과를 캐스팅하는 것이 좋지 않은 것으로 간주됩니다. 빈 포인터가 다른 오브젝트 포인터 유형에 내재적으로 형변환되므로 불필요합니다. 다른 말로하면 stdlib.h를 #include하는 것을 잊었거나 malloc()의 프로토 타입이없는 경우에는 진단에 어려움이 있습니다. C가 참조되기 전에 함수의 프로토 타입을 보지 않으면 함수가 암시 적으로 포인터 유형으로 변환 될 수없는 int를 반환한다고 가정합니다.

const와 관련하여
관련 문제