Den Unterschied sieht man am besten am erzeugten Code:

Code:
char *foo1 = "Text1";
char foo2[] = "Text2";

void bar (char*);

void inc()
{
	foo1[1] = 11;
	bar (foo1);

	foo2[1] = 22;
	bar (foo2);
}

-------------------------------------------------------

	.size	foo2, 6
foo2:
	.string	"Text2"

.LC0:
	.string	"Text1"

	.size	foo1, 2
foo1:
	.word	.LC0

inc:
	;; foo1[1] = 11;
	lds r30,foo1
	lds r31,(foo1)+1
	ldi r24,lo8(11)
	std Z+1,r24

	;; bar (foo1);
	lds r24,foo1
	lds r25,(foo1)+1
	rcall bar

	;; foo2[1] = 22;
	ldi r24,lo8(22)
	sts foo2+1,r24

	;; bar (foo2);
	ldi r24,lo8(foo2)
	ldi r25,hi8(foo2)
	rcall bar

	ret
foo1 enthält nur die Adresse des Strings "Text1"
foo2 iat der Anfang des Speicherbereichs, der mit "Text2" initialisiert wird.

Dementsprechend sehen Zugriff und Adressbildung auch anders aus.

Beide sind vom Typ char*, aber während foo1++ ok ist, gibt foo2++ einen Fehler.