2013-07-14 7 views
2
#include <stdio.h> 

int j; 
int *ptr; 

int main(void) 
{ 
    j = 13232323;//adress I want to assign 
    ptr = j;//assign the adress to the pointer 
    printf("%d",ptr); 
} 

ВЫВОД: 13232323Различия между Int переменной и указателя переменной в C

я делаю неправильно, как назначение адреса сразу на указатель? Указатель - это не что иное, как переменная, содержащая значение в адресной форме, поэтому я построил адрес, а затем назначил его указателю, он работает так, как предполагалось, за исключением того, что я не могу создать адрес, содержащий символы ABCDEF, поэтому, что большая разница между int и указателем?

EDIT: Этот код ничего не значит, но исключительно для целей тестирования

+0

Убедитесь, что вы включили предупреждения компилятора. Тогда причина вашей проблемы станет очевидной ... –

+0

использовать '% x' в printf вместо'% d' – perreal

+0

@OliCharlesworth Не появляется предупреждение, оно отлично работает, но как я могу назначить адрес, содержащий ABCDEF – user2556058

ответ

6

На самом деле то, что вы пытаетесь из вашего рвения., Я согласен, я тоже часто так.

В первую очередь, если вы храните 13232323 в переменной указателя, шестнадцатеричное значение этого параметра равно OXC9E8C3., Так что действительно во время назначения переменной указателя (ptr) не известно, действительно ли это действительный адрес или неверный адрес. Но когда вы разыскиваете этот адрес с *ptr, возникает проблема. Он пытается найти значение в адресе. . Тогда есть 2 случая.

  1. Действительно, если то, что вы назначили, является действительным адресом, тогда оно вернет значение. (Практически невозможно)
  2. В основном ваш адрес будет недействительным, поэтому программа выйдет из строя (ошибка сегментации).

Таким образом, даже если ваша программа компилируется, работает, до тех пор, пока вы не сохраните действующий адрес в ptr., ptr не имеет никакой пользы.

Вашего Вопрос: Он работает, как это было surposed быть, за исключением того, что я не могу построить адрес, содержащего символы ABCDEF, так, что большая разница между междунаром и указателем? Е ("% d", PTR);

Я думаю, что вы просите, в любом случае, я не могу хранить ABCDEF, следовательно, ptr работает так же, как int type, так что разница между целыми и указателем?

Здесь:

  1. Вы не можете почтительное целое значение, где в качестве указателя может это сделать. Следовательно, это называется указателем :)
  2. Вы видите только цифры, потому что вы печатаете адрес %d, пытаясь распечатать %x или %p.

Atlast, вы обратите внимание на предупреждение компилятора, warning: assignment makes pointer from integer without a cast, потому что ptr = j; в этом ptr имеет int* типа и j имеет int типа.

+0

Спасибо за ваш ответ, что произойдет, если я проигнорирую это предупреждение (не бросайте в int *), пока все работает нормально, – user2556058

+0

@ user2556058 Тогда тоже ничего не произойдет, программа будет работать нормально. Но 'ptr' станет непригодным. Таким образом, использование 'ptr' не требуется. Но если вы попытались почитать ptr, используя (* ptr) в любой момент, программа выйдет из строя. До тех пор, пока вы не захотите уважать (* ptr), проблем нет. Но ваша практика будет неправильной. –

+0

I'v внесла изменения в мой код: ptr = (int *) j; * ptr = 12; Когда я печатаю *** ptr **, он разбился, независимо от того, сколько раз я изменил адрес, чтобы ожидать использованного пространства, он всегда разбился, так что, что может привести к его краху? – user2556058

5

вам нужно использовать %x, или вы можете отправить *ptr в printf

printf("%d", *ptr);// if you are using this you need to know what are you pointing at, and that it will be an integer 

или

printf("%x", ptr); 

как в комментариях ниже, всегда лучше использовать %p вместо %x, потому что %x invoke undefined behaver. Также при использовании %p следует отдать свой указатель на (void *)

1

вам нужно PTR держать адрес J, выполнив следующие действия

ptr = &j; 

PTR захват, равный, адрес J

и вы хотите, чтобы напечатать содержание Что PTR указывает на следующей

printf("%d",*ptr); 

и получить адрес PTR сделать следующее

printf("%x",ptr); 

х на шестнадцатиричное представление

+0

Вы делаете что-то обычным способом, но я хочу назначить адрес вручную, а не использовать & для получения адреса, поэтому как я могу назначить определенный адрес указателю, например ABCDE1 – user2556058

+1

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

+0

Спасибо за головы, я знаю это сейчас – user2556058

1

Синтаксически, вы не делаете ничего плохого здесь. Вы можете в любом случае назначить один указатель другому, и поскольку они содержат только адреса, такие как тот, который вы назначили здесь, это то, что на самом деле происходит во время назначения указателя.
Но вы никогда не должны назначать случайный адрес и пытаться разыменовать его, потому что ваша программа не имеет доступа к ячейке памяти, если она не была выделена машиной. Вы должны запросить память с аппарата с помощью функции malloc().
Что касается различий между указателями и целыми числами, самым большим является то, что вы can't use a dereference operator (*) on an integer для доступа к значению по адресу, который он содержит.
И вы can construct addresses using ABCDEF, указав свое значение адреса 0X или 0x, чтобы обозначить шестнадцатеричную нотацию.

1
  • Я делаю неправильно, назначая адрес непосредственно указателю?

Да, только целые типы, которые должны работать непосредственно с указателями, как вы это intptr_t и uintptr_t, если они существуют. Если они не существуют, вы не должны это делать вообще. Даже тогда вам придется использовать явный приказ для преобразования.

  • Указатель ничего, кроме переменной содержит значение в виде адреса , поэтому я построил адрес, а затем присвоить его указателю, он работает, как это было surposed быть, за исключением того, что я не могу построить адрес, содержащий символы ABCDEF, так что в чем большая разница между int и указателем?

Нет, на некоторых архитектурных указателях могут быть более сложные животные, чем это. Память может быть, например, сегментирована, поэтому будет одна часть значения указателя, которое кодирует сегмент, а другое, которое кодирует смещение в этом сегменте. В наши дни такие архитектуры встречаются редко, но это то, что до сих пор разрешено стандартом C.

2

Ваш код недействителен. Язык C не позволяет это назначение

ptr = j; 

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

Если код был принят вашим компилятором, это просто означает, что ваш компилятор расширяет язык за пределы его формальных границ. Многие компиляторы делают это так или иначе. Однако, если ваш компилятор принял этот код без выдачи диагностического сообщения (предупреждение или ошибка), ваш компилятор серьезно нарушен.

Другими словами, поведение нашей программы очень мало (или ничего) в отношении языка C.

+0

Компилятор просто обязан выдать диагностическое сообщение. Предупреждение удовлетворяет этому требованию. –

2

В C вы можете сделать большую часть преобразования типов, даже типы полностью не связаны. Однако это может вызвать предупреждение. убедитесь, что ваше преобразование типов имеет смысл.

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