Здравствуйте!
Прошу объяснить разницу между двойными и одиночными указателями на примере двух приведённых ниже программ: они одинаковые, только первая использует одиночные указатели, а вторая - двойные.
Меня интересует, почему в первой программе строка ++(currentChar) не приводит к движению по строке чисел, а во второй соответствующая строка ++(*currentChar) приводит, другими словами, почему "область действия одиночного указателя ограничивается функцией, в пределах которой он задан" (кавычки, потому что знаю, что это может быть не точно) ?
Просьба не ругать за отсутствие элементарных познаний в языке C - я постепенно спускаюсь к нему с более высокого уровня (Objective-C), и до сих пор не выдавалось время изучить C системно.
Спасибо.
После ответов и обсуждения выяснилось, что на самом деле ключевая разница (ох, незнание основ!!) состоит в том, как передаются аргументы: в первом случае это просто currentChar, а во втором это ¤tChar. См. ответы и обсуждение.
Программа №1
void func1(const char *currentChar) {
printf("char is %c
", *currentChar);
++(currentChar);
}
int main(int argc, const char * argv[]) {
char *JSONCString2 = "123456789";
const char *currentChar = JSONCString2;
while (currentChar != NULL && *currentChar != '\0') {
func1(currentChar);
}
return 0;
}
Её вывод: бесконечное повторяющееся char is 1
Программа №2
void func1(const char **currentChar) {
printf("char is %c
", **currentChar);
++(*currentChar);
}
int main(int argc, const char * argv[]) {
char *JSONCString2 = "123456789";
const char *currentChar = JSONCString2;
while (currentChar != NULL && *currentChar != '\0') {
func1(¤tChar);
}
return 0;
}
char is 1
char is 2
char is 3
char is 4
char is 5
char is 6
char is 7
char is 8
char is 9
Program ended with exit code: 0
Ответ
Указатель - это обыкновенная переменная, которая хранит не данные, а некий адрес, который ссылается на ячейку данных. "Размер" этой ячейки зависит от типа указателя (не сам размер, а размер ячейки, которую он адресует, это важно для адресной арифметики, см. далее). Логично, что мы можем делать указатель на указатель с условно бесконечной глубиной вложенности. Можно получать адреса, относительно указателя "сдвигая" его вправо (прибавляя целое число) и влево (отнимая целое число) на размер типа указателя. UPD В первый раз мы передаем указатель по значению (каждый раз копируем значение), второй раз - по ссылке (работаем с ним непосредственно). Поэтому инкремент в первом случае не работает мы будем "топтаться на месте". из аргумента). Ну и при обращении к строке (в printf) в первый раз мы один раз извлекаем указатель (разыменовываем), а во второй - дважды, получая сначала адрес указателя на данные, а затем - и сами данные.
Комментариев нет:
Отправить комментарий