Я обнаружил проблему, проблема заключалась в том, что приложением по умолчанию для PDF было Microsoft Edge, я изменил его на Acrobat Reader, и теперь оно печатает.
Из-за правил приоритета операторов и того факта, что ++
- постфиксный оператор, add_one_v2 ()
разыменовывает указатель, но ++
фактически применяется к самому указателю . Однако помните, что C всегда использует передачу по значению: add_one_v2 ()
увеличивает свою локальную копию указателя, что никак не повлияет на значение, хранящееся по этому адресу. .
В качестве теста замените add_one_v2 ()
этими битами кода и посмотрите, как это повлияет на вывод:
void add_one_v2(int *our_var_ptr)
{
(*our_var_ptr)++; // Now stores 64
}
void add_one_v2(int *our_var_ptr)
{
*(our_var_ptr++); // Increments the pointer, but this is a local
// copy of the pointer, so it doesn't do anything.
}
Изображения стоят приблизительно тысячу слов (плюс-минус приблизительно миллион)..., и символы могут быть изображениями (и наоборот.)
те Soвёєfor из нас, кто ищет tl;dr
(оптимизированное потребление данных) и все же, хотят “ (главным образом) lossless” кодирование, векторные изображения/изображения/иллюстрации/демонстрации являются главными.
, Другими словами, просто проигнорируйте мои последние 2 оператора и посмотрите ниже.
Valid forms:
*a++ ≣ *(a++)
≣ (a++)[0] ≣ a++[0]
≣ 0[a++] // Don't you dare use this (“educational purposes only”)
// These produce equivalent (side) effects;
≡ val=*a,++a,val
≡ ptr=a,++a,*ptr
≡ *(ptr=a,++a,ptr)
*++a ≣ *(++a)
≣ *(a+=1) ≣ *(a=a+1)
≣ (++a)[0] ≣ (a+=1)[0] ≣ (a=a+1)[0] // ()'s are necessary
≣ 0[++a] // 0[a+=1], etc... “educational purposes only”
// These produce equivalent (side) effects:
≡ ++a,*a
≡ a+=1,*a
≡ a=a+1,*a
++*a ≣ ++(*a)
≣ *a+=1
≣ *a=*a+1
≣ ++a[0] ≣ ++(a[0])
≣ ++0[a] // STAY AWAY
(*a)++ // Note that this does NOT return a pointer;
// Location `a` points to does not change
// (i.e. the 'value' of `a` is unchanged)
≡ val=*a,++*a,valNotes
/* Indirection/deference operator must pr̲e̲cede the target identifier: */
❌ a++*; ❌
❌ a*++; ❌
❌ ++a*; ❌
Это одна из тех маленьких ошибок, которые делают C и C ++ так весело. Если вы хотите изменить свой мозг, выясните это:
while (*dst++ = *src++) ;
Это строковая копия. Указатели продолжают увеличиваться до тех пор, пока не будет скопирован символ с нулевым значением. Как только вы узнаете, почему этот трюк работает, вы больше никогда не забудете, как ++ работает с указателями.
PS Вы всегда можете переопределить порядок операторов с помощью круглых скобок. Следующее будет увеличивать указанное значение, а не сам указатель:
(*our_var_ptr)++;
Оператор '++' имеет более высокий приоритет над оператором '*', что означает, что адрес указателя будет увеличиваться перед разыменованием.
Оператор «+», однако, имеет более низкий приоритет, чем «*».
ОК,
*our_var_ptr++;
это работает следующим образом:
our_var_ptr
(которая содержит 63). our_var_ptr
затем увеличивается ПОСЛЕ оценки. Он меняет то место, куда указывает указатель, а не то, на что он указывает. Фактически это то же самое, что и следующее:
*our_var_ptr;
our_var_ptr = our_var_ptr + 1;
Имеет смысл? Ответ Марка Рэнсома является хорошим примером этого, за исключением того, что он фактически использует результат.
our_var_ptr
затем увеличивается ПОСЛЕ оценки. Он меняет то место, куда указывает указатель, а не то, на что он указывает. Фактически это то же самое, что и следующее:
*our_var_ptr;
our_var_ptr = our_var_ptr + 1;
Имеет смысл? Ответ Марка Рэнсома является хорошим примером этого, за исключением того, что он фактически использует результат.
our_var_ptr
затем увеличивается ПОСЛЕ оценки. Он меняет то место, куда указывает указатель, а не то, на что он указывает. Фактически это то же самое, что и следующее:
*our_var_ptr;
our_var_ptr = our_var_ptr + 1;
Имеет смысл? Ответ Марка Рэнсома является хорошим примером этого, за исключением того, что он фактически использует результат.
Как указывали другие, приоритет оператора приводит к тому, что выражение в функции v2 будет выглядеть как * (our_var_ptr ++)
.
Однако, поскольку это - постинкрементного оператора, было бы не совсем верно сказать, что он увеличивает указатель, а затем разыменовывает его. Если бы это было правдой, я не думаю, что вы получили бы 63 на выходе, поскольку он вернул бы значение в следующей ячейке памяти. На самом деле, я считаю, что логическая последовательность операций следующая:
Как объяснялось htw, вы не видит изменение значения указателя, потому что он передается по значению функции.
import getpass
print getpass.getuser()
См. Документацию модуля getpass .
getpass.getuser ( )
Возвращает «логин» пользователя. Доступность: Unix, Windows.
Эта функция проверяет переменные среды LOGNAME, USER, LNAME и USERNAME, по порядку, и возвращает значение первого который установлен в непустую строку. Если не заданы, имя входа из база паролей возвращается на системы, поддерживающие модуль pwd, но указатель равен
приращение указателя в add_one_v2
происходит после разыменованияПочему?
- Потому что
++
связывает более жестко чем*
(как разыменование или умножение), поэтому приращение вadd_one_v2
применяется к указателю, а не к тому, на что он указывает.- post приращения происходят после оценка термина, поэтому разыменование получает первое значение в массиве (элемент 0).
our_var_ptr - указатель на некоторую память. т.е. это ячейка памяти, в которой хранятся данные. (в данном случае 4 байта в двоичном формате int).
* our_var_ptr - это разыменованный указатель - он переходит в то место, на которое «указывает» указатель.
++ увеличивает значение на единицу.
поэтому , * our_var_ptr = * our_var_ptr + 1
разыменовывает указатель и добавляет единицу к значению в этом месте.
Теперь добавьте приоритет оператора - прочтите его как (* our_var_ptr) = (* our_var_ptr) +1
и вы видите, что разыменование происходит первым, поэтому вы берете значение и увеличиваете его.
В другом примере оператор ++ имеет более низкий приоритет, чем *, поэтому он принимает указатель, который вы передали в , добавил к нему один (теперь он указывает на мусор), а затем возвращается. (помните, что значения всегда передаются по значению в C, поэтому, когда функция возвращает исходный указатель testvar, остается неизменным, вы только изменили указатель внутри функции).
Мой совет, при использовании разыменования (или чего-либо еще) используйте скобки чтобы ваше решение было ясным. Не пытайтесь запомнить правила приоритета, так как однажды вы в конечном итоге будете использовать другой язык, который немного отличается от них, и вы запутаетесь. Или старый и в конечном итоге забываешь, что имеет более высокий приоритет (как я делаю с * и ->).
Попытайтесь запомнить правила приоритета, поскольку однажды вы в конечном итоге будете использовать другой язык, в котором они будут немного отличаться, и вы запутаетесь. Или старый и в конечном итоге забываешь, что имеет более высокий приоритет (как я делаю с * и ->). Попытайтесь запомнить правила приоритета, поскольку однажды вы в конечном итоге будете использовать другой язык, в котором они будут немного отличаться, и вы запутаетесь. Или старый и в конечном итоге забываешь, что имеет более высокий приоритет (как я делаю с * и ->).