2013-05-27 2 views
1

그래서 C에서 약 1 년 동안 아무 것도 쓰지 않았고 오늘 아침에 뭔가 쓸 것이라고 생각했습니다. 나/아주/빨리 문제가 발생했습니다. 아래의 매우 기본적인 코드가 실행되지 않습니다 : 나는 다음과 같은 오류가C 컴파일러에 따라 C 명령 줄 인수가 int입니다. 무슨 일이야?

gcc dink.c -o dink 
dink.c: In function ‘main’: 
dink.c:6:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat] 
./dink menkmenk 
make: *** [all] Segmentation fault (core dumped) 

에 가야 뭐죠

#include <stdlib.h> 
#include <stdio.h> 
int main(int argc, char* argv) 
{ 
     printf("arg is %s \n", argv[1]); 
} 

?

편집 : 나는 코드가 작동하지 않는 이유에 대한 답변을 얻고 있지만 컴파일러가 두 번째 인수에 int를 보유하고 있다고 생각하는 이유를 알고 싶습니다.

답변

5

다른 답변은 문제를 해결하는 방법을 알려줍니다. 여기에 그 특별한 오류 메시지가있는 이유가 있습니다.

C에는 표현식에서 유형을 변경하는 규칙이 있습니다 ... 대부분 자동으로 다른 유형으로 변환됩니다. 내가 대학에 다닐 때, 내가 택한 수업에서 이러한 전환은 비공식적으로 "판촉"이라고 불렸지 만 올바른 기술 용어는 "전환"이라고 생각합니다 (아래 @Steve Jessop의 의견 참조).

다음은 예입니다 :이 예에서

float f = 3.14f + 2; 

, 우리는 정수 float로 추가 할 것을 요청한다. C 타입 규칙에 따르면 정수 값은 float (표준에 설명 된 "일반적인 자동 변환"의 일부로)로 변환되고 두 개의 부동 소수점이 함께 더해져 우리가 입력 한 것과 같은 결과를냅니다 :

float f = 3.14f + 2.0f; 

그런데 우리가 f 접미어를 남기면 더 많은 전환이 일어날 것입니다.이 식을 고려 : 3.14 이후

float f = 3.14 + 2; 

f 접미사로 선언되지 않았습니다를,이 유형 double의 상수이다. 그런 다음 정수 2double으로 변환되고 더해지며 결과는 double입니다. 그러나 float 변수에 할당해야합니다. 따라서 double에서 float으로 변환되며 double에서 float으로 변환 할 때 가능한 정밀도 손실에 대한 컴파일러 경고가 표시됩니다.

어쨌든, 질문으로 돌아 : 당신이 유형 char *argv를 선언 할 때

한 다음 argv[1] 언급, 표현 argv[1]의 유형은 유형 char했다. 그러나 C가 형식을 char에서 int으로 변환했기 때문에 혼란스러운 오류 메시지가 나타납니다.

현재 C의 타입 변환 규칙에 대한 자세한 내용을보실 수 있습니다 :

http://www.eskimo.com/~scs/cclass/int/sx4cb.html

편집 : 지속적 @ 스티브의 코멘트에 응답 단어 대신 "홍보"가 아닌 "변환"을 사용하여 위의 변경 제시.

+0

답변을 주셔서 감사합니다. 그러나 C가 왜 char을 int로 승격하려고 시도 했나요? – MYV

+1

용어 : 첫 번째 예제에서'2'를'float'로 변환하는 것은 "일반적인 산술 변환"의 일부입니다. * 표준 *이 "판촉"이라고 부르는 항목의 일부가 아닙니다. 영어로는 가치 보존 형을 더 큰 유형으로 변환하여 "판촉"이라고 부르는 것이 합리적입니다. 질문자 코드에서'char'에서'int' 로의 변환은 varargs 인수 표현식 (C99의 6.5.2.2/7)에 적용되는 "기본 인수 승격"때문입니다. –

2

main의 서명이 잘못되었습니다. argv은 문자열 배열이어야합니다. 즉

int main(int argc, char* argv[]) 
//       ^^ 
3

시도

int main(int argc, char** argv) 

또는

int main(int argc, char* argv[]) 
+0

시도 만하는 것이 아닙니다. 당신은 더 독단적이어야합니다. :-) – Jens

1

그것은 char **argv 또는 char *argv[]로 argv를 선언하는 것이 더 일반적이다.

char *argv은 argv가 char에 대한 포인터임을 나타냅니다. 이는 다소 다릅니다.

따라서

int main(int argc, char **argv) 

또는

int main(int argc, char *argv[]) 

당신이 기대하는 것과 라인에서 더 많은되어야한다.

또한 argv[1]을 이와 같이 요청하는 것은 바람직하지 않습니다. 일반적으로 그러한 주장이 있는지 적어도 확인해야합니다.

관련 문제