В этом объявлении
char *str1="Hi", *str2 = "Bye";
объявлены две локальные переменные str1
и str2
с автоматическим c сроком хранения.
Они инициализируются по адресам первой символы строковых литералов, которые имеют длительность хранения c.
Таким образом, значение str1
является адресом первого символа строкового литерала "Hi"
. Значением выражения &str1
является адрес самой локальной переменной str1
.
Это можно представить следующим образом
&str1 ---> str1 ---> "Hi"
Массивы являются смежными экстентами памяти. Таким образом, адрес самого массива и адрес его первого элемента совпадают. Это адрес объема памяти, занятого массивом.
Вы можете представить это следующим образом
| 1 | 2 | 3 | 4 | 5 |
^
|
&arr----
^
|
arr-----
Обратите внимание, что указатели массива, используемые в выражениях с редкими исключениями, преобразуются указатели на их первые элементы. Так что используйте din для вызова printf выражение arr
эквивалентно &arr[0]
.
Относительно вашего комментария
Влад У меня есть сомнения относительно строковой константы. Почему можно не изменяем ли мы этот char * s = "HI", но мы можем изменить этот char * s [] = "HI" Я знаю, что во втором случае это простой массив, но не могли бы вы пояснить, почему я не могу изменить строковую константу * 1031? *
затем в соответствии со стандартом C (6.4.5 Строковые литералы)
7 Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено.
Обратите внимание на это объявление
char *s[]="HI";
недопустимо. Там объявлен массив указателей. Таким образом, чтобы инициализировать его, вы должны написать
char * s[] = { "HI" };
И вы можете изменить элементы массива, назначив им другие строковые литералы. То есть вы можете изменять сами указатели, а не строковые литералы, на которые указывают указатели.