2015-06-08 2 views
-2

Может ли кто-нибудь объяснить мне, что делает эта программа?Что означает (unsigned char *) & niz [10]?

#include<stdio.h> 
int main() 
{ 
    unsigned char niz[20000]; 
    unsigned char *pok; 
    pok = (unsigned char*)&niz[10]; 
    printf("%s",*pok); 
    return 0; 
} 

При запуске программы она говорит:

предупреждение: формат %s ожидает аргумент типа char *,
но аргумент 2 имеет тип int [-Wformat =] printf("%s",*pok);

Что делает линия pok = (unsigned char*)&niz[10];?

Почему невозможно распечатать результат в терминале?

+1

Программа будет демонстрировать неопределенное поведение в двух учетных записях: использование неинициализированной переменной и использование неправильного формата в 'printf'. –

+0

Подумайте об этом: каков тип выражения '* pok' в вызове' printf'? – juanchopanza

+0

Я попытался с 'printf ("% d ", * pok)', и он говорит 0. Почему допустимо, что если '* pok' является типом char? – HardRock

ответ

2

линия, о которой вы спрашиваете:

printf ("%s", * pok); 

проходит два аргумента printf. Первая - это строка формата "%s". Второй * pok, то есть значение, при котором pok баллов. Так как вы написали pok = & niz[10]; (с ненужным приведением к (unsigned char *) - бросить как можно меньше!), pok точек на niz[10], который является неинициализированными unsigned char, которая может иметь любое значение от 0 к UCHAR_MAX; потому что это передается аргументу неуказанного типа, перед передачей ему присваивается int, но все же имеет такое же числовое значение.

Управление теперь переходит к printf, который извлекает строку формата "%s" и, поскольку он видит спецификатор строки, интерпретирует остальную часть списка аргументов как содержащую адрес строки, из которой он пытается получить символы в строка по одному, пока не найдет завершающий нуль. Что происходит тогда неопределенные, но есть два возможных варианта:

  • Если тип char * имеет такой же размер, как int, он будет извлекать значение niz[10], и интерпретировать его как очень низкий адрес. Этот адрес, скорее всего, будет считаться недействительным процессором, что приведет к нарушению адреса и остановке вашей программы.
  • Если тип char * больше int, он подберет некоторые дополнительные биты, которые могут находиться в верхней или нижней части адреса, в зависимости от того, как ваша система организует память. Вы получите довольно случайный адрес, который, вероятно, будет недействительным, с тем же результатом, что и в предыдущем случае.

В любом случае возможно, что адрес будет таким, который вы можете читать; в этом случае программа будет печатать содержимое этого и последующих адресов в предположении, что они являются печатаемыми символами, что может сделать странные вещи с вашим терминалом, если они не являются (если вы не подключите вывод к команде, такой как od -oc). Это будет продолжаться до тех пор, пока один из этих непредсказуемых символов не будет равен нулю, и в этом случае он остановится или адрес станет недействительным, и в этом случае ваша программа остановится с нарушением адреса.

+0

Большое вам спасибо за это объяснение ... – HardRock

+0

Совсем не рад помочь! – PJTraill

+0

@PJTraill Во второй строке это должно быть pok = & niz [10]; –

1

Ваша пятая линия

pok=(unsigned char *)&niz[10]; 

присвоит адрес

char niz[10] 

указателю пок.

И в вашей шестой строке в основном печатается значение по адресу, на котором POK точки которых очевидна

char niz[10] 

Но одна вещь, которую вы делаете неправильно, что вы пропускании неверный формат спецификатор% s если вы хотите напечатать значение по адресу, на котором указывает pok, вы должны использовать% c вместо% s.

1
unsigned char niz[20000] 

// объявляет массив 20000 ASCII символов

unsigned char *pok; 

// объявляет указатель на символ. Таким образом, пок это переменная, которая будет содержать Устранять любые неподписанные символ переменной

pok=(unsigned char *)&niz[10]; 

// пок получает присвоен адрес 11-го символа массива (индекс начинается с 0)

printf("%s",*pok); 

// «* pok» пытается напечатать конкретный символ по адресу, содержащемуся в pok. Однако% s попытается напечатать строку с нулевым завершением, начиная с адреса, содержащегося в ptr. Следовательно, предупреждение

Смежные вопросы