Самый простой ответ:
Разница здесь в том, что
char *s = "Hello world";
поместит Привет мир в режиме только для чтения части памяти и делает sa указателем на это, делая любую операцию записи в этой памяти незаконно. Во время выполнения:
char s[] = "Hello world";
помещает символьной строки в памяти и копирует строку в вновь выделенной памяти на стеке только для чтения. Таким образом, производство
s[0] = 'J';
юридический.
Более длинное объяснение будет включать в себя какие сегменты памяти хранится в и сколько памяти выделяется:
Example: Allocation Type: Read/Write: Storage Location: Memory Used (Bytes):
===========================================================================================================
const char* str = "Stack"; Static Read-only Code segment 6 (5 chars plus '\0')
char* str = "Stack"; Static Read-only Code segment 6 (5 chars plus '\0')
char* str = malloc(...); Dynamic Read-write Heap Amount passed to malloc
char str[] = "Stack"; Static Read-write Stack 6 (5 chars plus '\0')
char strGlobal[10] = "Global"; Static Read-write Data Segment (R/W) 10
Ссылки
- Что такое разница между char s [] и char * s в C?, Accessed 2014-09-03,
<https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c>
- Разница между заявленной строкой и выделенной строки, Accessed 2014-09-03,
<https://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>
Редактировать
Для решения этой редактирование в вопросе и комментарий, выпущенный вместе с ним, я добавил примечания к вашему решению:
#include <stdio.h>
int main() {
char ch[] = "Hello"; /* OK; Creating an array of 6 bytes to store
* 'H', 'e', 'l', 'l', 'o', '\0'
*/
char *p1 = ch; /* OK; Creating a pointer that points to the
* "Hello" string.
*/
char *p2 = p1; /* OK; Creating a second pointer that also
* points to the "Hello" string.
*/
char *p3 = *p1; /* BAD; You are assigning an actual character
* (*p1) to a pointer-to-char variable (p3);
* It might be more intuitive if written in
* 2 lines:
* char* p3;
* p3 = *p1; //BAD
*/
printf("ch : %s\n", ch); /* OK */
printf("p1 address [%d] value is %s\n", p1, *p1); /* Bad format specifiers */
printf("p2 address [%d] value is %s\n", p2, *p2); /* Bad format specifiers */
printf("p3 address [%d] value is %s\n", p3, *p3); /* Bad format specifiers */
return 0;
}
Итак, три основных ошибки.
- Вы присваиваете
char
значение в pointer-to-char
переменной. Ваш компилятор должен предупредить вас об этом. (char *p3 = *p1
).
- В зависимости от вашего компилятора вам может понадобиться использовать указатель формата
%p
для печати адреса, а не спецификатор формата %d
(целочисленный).
- Вы используете строку спецификатора
%s
с типом данных char
(то есть: printf("%s", 'c')
неверен). Если вы печатаете один символ, вы используете спецификатор формата %c
, а соответствующий аргумент должен быть символом (например: 'c', char b и т. Д.). Если вы печатаете целую строку, вы используете спецификатор формата %s
, а аргумент - указатель на символ.
Примеры
#include <stdio.h>
int main(void) {
char c = 'H'; // A character
char* pC = &c; // A pointer to a single character; IS NOT A STRING
char cArray[] = { 'H', 'e', 'l', 'l', 'o' }; // An array of characters; IS NOT A STRING
char cString[] = { 'H', 'e', 'l', 'l', 'o', '\0' }; // An array of characters with a trailing NULL charcter; THIS IS A C-STYLE STRING
// You could also replace the '\0' with 0 or NULL, ie:
//char cString[] = { 'H', 'e', 'l', 'l', 'o', (char)0 };
//char cString[] = { 'H', 'e', 'l', 'l', 'o', NULL };
const char* myString = "Hello world!"; // A C-style string; the '\0' is added automatically for you
printf("%s\n", myString); // OK; Prints a string stored in a variable
printf("%s\n", "Ducks rock!"); // OK; Prints a string LITERAL; Notice the use of DOUBLE quotes, " "
printf("%s\n", cString); // OK; Prints a string stored in a variable
printf("%c\n", c); // OK; Prints a character
printf("%c\n", *pC); // OK; Prints a character stored in the location that pC points to
printf("%c\n", 'J'); // OK; Prints a character LITERAL; Notice the use of SINGLE quotes, ' '
/* The following are wrong, and your compiler should be spitting out warnings or even not allowing the
* code to compile. They will almost certainly cause a segmentation fault. Uncomment them if you
* want to see for yourself by removing the "#if 0" and "#endif" statements.
*/
#if 0
printf("%s\n", c); // WRONG; Is attempting to print a character as a string, similar
// to what you are doing.
printf("%s\n", *pC); // WRONG; Is attempting to print a character as a string. This is
// EXACTLY what you are doing.
printf("%s\n", cArray); // WRONG; cArray is a character ARRAY, not a C-style string, which is just
// a character array with the '\0' character at the end; printf
// will continue printing whatever follows the end of the string (ie:
// random memory, junk, etc) until it encounters a zero stored in memory.
#endif
return 0;
}
Листинг - Предлагаемое решение
#include <stdio.h>
int main() {
char ch[] = "Hello"; /* OK; Creating an array of 6 bytes to store
* 'H', 'e', 'l', 'l', 'o', '\0'
*/
char *p1 = ch; /* OK; Creating a pointer that points to the
* "Hello" string.
*/
char *p2 = p1; /* OK; Creating a second pointer that also
* points to the "Hello" string.
*/
char *p3 = p1; /* OK; Assigning a pointer-to-char to a
* pointer-to-char variables.
*/
printf("ch : %s\n", ch); /* OK */
printf("p1 address [%p] value is %s\n", p1, p1); /* Fixed format specifiers */
printf("p2 address [%p] value is %s\n", p2, p2); /* Fixed format specifiers */
printf("p3 address [%p] value is %s\n", p3, p3); /* Fixed format specifiers */
return 0;
}
Пример вывода
ch : Hello
p1 address [0x7fff58e45666] value is Hello
p2 address [0x7fff58e45666] value is Hello
p3 address [0x7fff58e45666] value is Hello
Чтение раздела 6 [comp.lang.c FAQ] (http://www.c-faq.com/). –