배열에 대한 질문입니다.

freegagamel의 이미지

안녕하세요.
요즘 전웅님의 C언어 펀더멘탈을 보고 있습니다. 포인터와 배열부분을 따라하면서 몇 가지를 바꿔보면서 실습을 하는데요 아래의 차이를 아시는분 계시면 설명 부탁드립니다.

#include <stdio.h>

int main(void)
{
	int a[];
	int (*pai)[];
	pai = &a;
	printf("%d,%d\n", pai, &a);
	
	return (0);
}

anjuta에서 아래와 같은 warning메세지가 뜹니다.
array1.c:5 :warning : array 'a' assumed to have one element

int a[]을 int a[10]으로 변경하고 경고가 안뜨더군요.

int a[]와 int a[10]간의 배열의 크기를 지정하고 안하고의 차이가 있나요?

while1do의 이미지

제가 처음 C를 배울때는
배열 크기를 명시적으로 선언 하지 않을때는 초기화를 같이 해줘야 하는 것으로 알고 있습니다.

int a[] = {1, 2, 3}; 과 같이요.

이게 표준인지 아닌지는 잘 모르겠습니다.

보통은 컴파일러가 에러를 낼텐데..님께서 사용하시는 컴파일러는 저걸 그냥 int a[1]; 로 해석 해버리는 것 같습니다.

PS. gcc 3.3.5, VS 2005 모두 에러 나네요.

7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

anjuta도 gcc를 쓸텐데 오류가 안나는게 이상한 것 같은데요? ~_~
어쩌면 while1do님이 워닝을 오류로 착각하신 걸지도 모르겠습니다.

doldori의 이미지

잘못된 프로그램입니다. 398페이지에 보면 "연결이 없는 명칭을 갖는 대상체는
선언될 때 반드시 (불완전형이 아닌) 완전한 대상체형으로 선언되어야 한다"고
되어 있지요. 블럭 내부의 대상체는 연결이 없으므로 배열 크기를 생략한 선언은
허락되지 않습니다.

이 코드를 다음처럼 바꾸면 적법한 프로그램이 됩니다.

#include <stdio.h> 

int a[];   // (1)

int main(void) 
{ 
   int (*pai)[]; 
   pai = &a; 
   printf("%d,%d\n", pai, &a); 
    
   return (0); 
}
//   (2)  int a[1] = { 0 };
 

이 경우 a는 외부 연결을 갖는 대상체이므로 (1)과 같은 선언이 허락되고 이때
초기값이 지정되지 않았으므로 (1)은 임시 정의(tentative definition)가 됩니다.
그리고 파일 끝까지 완전한 정의가 주어지지 않았으므로 파일 끝에서 (2)와 같이
정의가 된 것으로 간주합니다. 아마 gcc가 내는 경고는 이것을 자동 변수까지 확장하여
허용하는 모양인데 이식성은 없음을 유의하십시오.
전웅의 이미지

freegagamel wrote:
안녕하세요.
요즘 전웅님의 C언어 펀더멘탈을 보고 있습니다. 포인터와 배열부분을 따라하면서 몇 가지를 바꿔보면서 실습을 하는데요 아래의 차이를 아시는분 계시면 설명 부탁드립니다.

#include <stdio.h>

int main(void)
{
	int a[];
	int (*pai)[];
	pai = &a;
	printf("%d,%d\n", pai, &a);
	
	return (0);
}

anjuta에서 아래와 같은 warning메세지가 뜹니다.
array1.c:5 :warning : array 'a' assumed to have one element

int a[]을 int a[10]으로 변경하고 경고가 안뜨더군요.

int a[]와 int a[10]간의 배열의 크기를 지정하고 안하고의 차이가 있나요?

이론적인 정확한 설명은 doldori 님께서 해주셨습니다.

크기가 명시되지 않은 외부 배열이 임시 정의(tentative definition)로
인식되고, 또 프로그램 소스(정확히는 translation unit)의 끝에서 초기치
하나가 주어져 요소 하나를 갖는 배열로 인식되는 부분은 (겉보기에는
이상해 보이지만) 표준에 의해 보장되는 부분입니다.

저 역시 해당 내용을 처음 접했을 때 오히려 많은 컴파일러가 이를
올바르게 구현하고 있음에 놀란 기억이 있습니다 (그 과정에서 Comeau
Computing 사 대표와 긴 메일을 주고 받은 므흣한 기억이 나는군요).

하지만, 제 책에 그와 같은 예를 포함한 의도는 그와 같은 배열 선언
방식을 널리 알리고자 함이 아닙니다. 바로 표준에서 컴파일러의 진단
메시지가 갖는 정확한 위치를 전달하고자 함이었습니다. 즉, (예외가 있긴
하지만) 컴파일러는 잘못된 프로그램에 침묵할 수도, 올바른 프로그램에
조언을 할 수도 있다는 것을 알리기 위한 예로 그와 같은 미묘한 부분을
끌어다 사용했을 뿐입니다.

달을 가리키는 손가락이 아닌 달을 바라봐 주셨으면 하는 마음에 글
남깁니다.

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

freegagamel의 이미지

전부는 아니지만 다시 책을 더듬어 보니 내용을 알 수 있었습니다.
중반부를 겨우 겨우 졸린 눈을 부벼가며 보고 있습니다. ^^;;;

초반에 의욕으로 시작하였습니다만..중반이 되어서는 2~3일에 한번 정도 들쳐보는 꼴이니..이러다 베개로 삼는거 아닌가 모르겠습니다. ^^
2월 내에 끝내고 다시 한번 보면서 곱씹어 봐야 되겠습니다.

답변주신 모든 분들께 감사드립니다. (_ _)

새해 복 많이 받으세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.