почему я получаю вывод пустым? - PullRequest
1 голос
/ 17 мая 2019

почему я получаю вывод пустым?указатели могут изменяться, но не могут читать. Почему?

#include <iostream>
using namespace std;

int main(){
    int a = 0;
    char *x1,*x2,*x3,*x4;
    x1 = (char *)&a;
    x2 = x1;x2++;
    x3 = x2;x3++;
    x4 = x3;x4++;
    *x1=1;
    *x2=1;
    *x3=1;
    *x4=1;

    cout <<"@" << *x1 << " " << *x2 << " " << *x3 << " " << *x4 << "@"<<endl ;
    cout << a << endl;
}
[Desktop]? g++ test_pointer.cpp
[Desktop]? ./a.out
@   @
16843009

Я хочу прочитать значение целого числа, используя тип указателей типа char.так что я могу читать побайтно.

Ответы [ 5 ]

6 голосов
/ 17 мая 2019

Вы транслируете char с. Они автоматически распознаются ASCII для вас IOStreams *, поэтому вы видите (или, скорее, не видите) непечатаемые символы (фактически все 0x01 байт).

Вы можете привести к int, чтобы увидеть числовое значение, и, возможно, добавить std::hex для обычного вида.

Пример:

#include <iostream>
#include <iomanip>

int main()
{
    int a = 0;

    // Alias the first four bytes of `a` using `char*`
    char* x1 = (char*)&a;
    char* x2 = x1 + 1;
    char* x3 = x1 + 2;
    char* x4 = x1 + 3;

    *x1 = 1;
    *x2 = 1;
    *x3 = 1;
    *x4 = 1;

    std::cout << std::hex << std::setfill('0');
    std::cout << '@' << std::setw(2) << "0x" << (int)*x1
              << ' ' << std::setw(2) << "0x" << (int)*x2
              << ' ' << std::setw(2) << "0x" << (int)*x3
              << ' ' << std::setw(2) << "0x" << (int)*x4
              << '@' << '\n';
    std::cout << "0x" << a << '\n';
}

// Output:
//   @0x01 0x01 0x01 0x01@
//   0x1010101

( живая демонстрация )

Те, кто говорит, что ваша программа имеет неопределенное значение, неверны (при условии, что в вашем int есть как минимум четыре байта); алиасинг объектов через char* специально разрешен.

Вывод 16843009 правильный; это равно 0x01010101, которое вы снова увидите, если переведите свой поток в шестнадцатеричный режим.


N.B. Некоторые люди рекомендуют reinterpret_cast<char*>(&a) и static_cast<int>(*x1) вместо бросков в стиле C, хотя лично я считаю их уродливыми и ненужными в данном конкретном случае. Для вывода вы можете, по крайней мере, написать +*x1, чтобы получить «бесплатное» повышение до int (через унарный оператор +), но это не очень самодокументируется.


* Технически это что-то вроде противоположности; IOStreams обычно автоматически преобразует ваши числа, логические значения и все в правильные символы ASCII, чтобы они отображались правильно на экране. Для char этот шаг пропускается, при условии, что вы уже предоставляете нужное значение ASCII.

2 голосов
/ 17 мая 2019

Предполагая, что int имеет длину не менее 4 байтов в вашей системе, программа обрабатывает 4 байта int a.

В результате 16843009 является десятичным значением 0x01010101, поэтомуэто, как и следовало ожидать.

Вы не видите ничего в первой строке вывода, потому что вы пишете 4 символа двоичного значения 1 (или 0x01), которые являются невидимыми символами (ASCII SOH)).

Когда вы измените свою программу следующим образом

*x1='1';
*x2='3';
*x3='5';
*x4='7';

, вы увидите вывод с ожидаемыми символами

@1 3 5 7@
926233393

Значение 926233393 является десятичным представлением0x37353331, где 0x37 - значение ASCII символа '7' и т. д.

(Эти результаты действительны для архитектуры с прямым порядком байтов.)

1 голос
/ 17 мая 2019

Посмотрите на ваши заявления x

char *x1,*x2,*x3,*x4;

это указатели на chars (символы).

В выводе вашего потока они интерпретируются как печатные символы. Краткий обзор таблицы ascii позволяет увидеть, что нижние числа не могут быть напечатаны.

Поскольку ваш int a равен нулю, x, указывающие на отдельные байты, равны нулю.

Одной из возможностей получить читабельный вывод будет приведение символов к int, чтобы поток выводил числовое представление вместо символа ascii:

cout <<"@" << int(*x1) << " " << int(*x2) << " " << int(*x3) << " " << int(*x4) << "@"<<endl ;
0 голосов
/ 17 мая 2019

Вы можете использовать унарный + для преобразования типа символа (печатается как символ) в целочисленный тип (печатается как число):

cout <<"@" << +*x1 << " " << +*x2 << " " << +*x3 << " " << +*x4 << "@"<<endl ;

См. интегральное продвижение :

0 голосов
/ 17 мая 2019

Если я правильно понял вашу проблему, это решение

#include <stdio.h>
#include <iostream>
using namespace std;

int main(){
    int a = 0;
    char *x1,*x2,*x3,*x4;
    x1 = (char*)&a;
    x2 = x1;x2++;
    x3 = x2;x3++;
    x4 = x3;x4++;
    *x1=1;
    *x2=1;
    *x3=1;
    *x4=1;
    cout <<"@" << (int)*x1 << " " << (int)*x2 << " " << (int)*x3 << " " << (int)*x4 << "@"<<endl ;
    cout << a << endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...