В Java все находится в форме класса.
Если вы хотите использовать любой объект, тогда у вас есть две фазы:
Пример:
Object a;
a=new Object();
То же самое для концепции массива
Item i[]=new Item[5];
i[0]=new Item();
Если вы не дают секцию инициализации, тогда возникает NullpointerException
.
"s" не является "символом* ", это - "символ [4]". И так", & s" не "символ ** ", но на самом деле "указатель на массив 4 characater". Ваш компилятор может рассматривать" & s", как будто Вы записали "& s [0]", который является примерно тем же самым, но является "символом*".
, Когда Вы пишете "символ ** p = &s"; Вы пытаетесь сказать, что "Я хочу, чтобы p был установлен на адрес вещи, которая в настоящее время указывает на "asd". Но в настоящее время нет ничего который точки к "asd". Существует только массив, который содержит "asd";
char s[] = "asd";
char *p = &s[0]; // alternately you could use the shorthand char*p = s;
char **pp = &p;
Да, Ваш компилятор ожидает пусто *. Просто бросьте их для освобождения *.
/* for instance... */
printf("The value of s is: %p\n", (void *) s);
printf("The direction of s is: %p\n", (void *) &s);
При передаче названия массива как аргумент функции его рассматривают, как будто Вы передали адрес массива. Так & s и s являются идентичными аргументами. См. K& R 5.3. & s [0] совпадает с & s, так как это берет адрес первого элемента массива, который совпадает со взятием адреса самого массива.
Для всего другие, хотя все указатели являются чрезвычайно ячейками памяти, они все еще вводятся, и компилятор предупредит о присвоении одного типа указателя на другого.
void* p;
говорит, что p является адресом памяти, но я не знаю то, что находится в памяти char* s;
, говорит, что s является адресом памяти, и первый байт содержит символ char** ps;
, говорит, что PS является адресом памяти, и четыре байта там (для 32-разрядной системы) содержат указатель типа char*. cf http://www.oberon2005.ru/paper/kr_c.pdf (версия электронной книги K& R)
Это не указатель на символ char*
, а указатель на массив из 4 символов: char* [4]
. С g ++ он не компилируется:
main.cpp: в функции 'int main (int, char **)': main.cpp: 126: ошибка: невозможно преобразовать 'char (*) [4] 'to' char ** 'при инициализации
Более того, на страницах man linux написано :
p
Аргумент указателя void * печатается в шестнадцатеричном формате (как будто% # x или% # lx). Это должен быть указатель на пустоту.
Вы можете изменить свой код на:
char* s = "asd";
char** p = &s;
printf("The value of s is: %p\n", s);
printf("The address of s is: %p\n", &s);
printf("The value of p is: %p\n", p);
printf("The address of p is: %p\n", &p);
printf("The address of s[0] is: %p\n", &s[0]);
printf("The address of s[1] is: %p\n", &s[1]);
printf("The address of s[2] is: %p\n", &s[2]);
результат:
Значение s: 0x403f00
Адрес s: 0x7fff2df9d588
Значение p: 0x7fff2df9d588
Адрес p: 0x7fff2df9d580
Адрес s [0]: 0x403f00
Адрес из s [1]: 0x403f01
Адрес s [2]: 0x403f02
строка изменения:
символ s [] = "asd";
к:
символ *s = "asd";
и вещи станет более ясным
Вы не можете изменить значение (т.е. адрес) статический массив. В технических терминах lvalue массива является адресом своего первого элемента. Следовательно s == &s
. Это - просто причуда языка.
Обычно, это полагало, что плохой стиль излишне бросает указатели на (пусто*). Здесь, однако, Вам нужны броски к (пусто*) на printf аргументах, потому что printf является variadic. Прототип не говорит компилятор что тип преобразовать указатели на на сайте вызова.
Вы использовали:
char s[] = "asd";
Здесь s фактически указывает на байты «asd». Адрес s также указывает на это местоположение.
Если бы вы использовали:
char *s = "asd";
значение s и & s было бы другим, поскольку s фактически было бы указателем на байты «asd».
Вы использовали:
char s[] = "asd";
char **p = &s;
Здесь s указывает на байты «asd». p - указатель на указатель на символы, и для него задан адрес символов. Другими словами, у вас слишком много косвенных указаний в p. Если бы вы использовали char * s = "asd", вы могли бы использовать эту дополнительную косвенность.