указатель программы - PullRequest
       12

указатель программы

0 голосов
/ 27 апреля 2010

Я пытаюсь некоторые программы в c сталкиваются с проблемой с этой программой Может ли кто-нибудь сказать мне, в чем проблема с этим, и я также хочу знать, что, когда в приведенном выше случае, если значение указателя увеличивается, то он перезаписывает предыдущий адрес значения как

#include<stdio.h>
int main()
{
    int a=9,*x;
    float b=3.6,*y;
    char c='a',*z;
    printf("the value is %d\n",a);
    printf("the value is %f\n",b);
    printf("the value is %c\n",c);
    x=&a;
    y=&b;
    z=&c;
    printf("%u\n",a);
    printf("%u\n",b);
    printf("%u\n",c);
    x++;
    y++;
    z++;
    printf("%u\n",a);
    printf("%u\n",b);
    printf("%u\n",c);
    return 0;
}

предположим, что значение, которое мы получили в вышеуказанной программе (без увеличения значения указателя) 65524 65520 65519 и после приращения значение указателя равно 65526 ​​(как 2 приращения для int) 65524 (как 4 приращения для поплавка) 65520 (как 1 приращение для переменной char)

тогда, если в этом случае новый адрес указателя перезапишет содержимое предыдущего адреса и какое значение будет содержаться по новому адресу

Ответы [ 3 ]

4 голосов
/ 27 апреля 2010

Вы не можете просто увеличивать x, y, z вот так.
Вы не можете гарантировать, что они размещены в памяти в таком порядке - адрес памяти после 'x' может быть любым.

Изменить, чтобы уточнить: Да, вы можете увеличивать указатель, но вы должны быть уверены, что «владеете» памятью, на которую вы тогда указываете - обычно памятью в строке или массиве.

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

2 голосов
/ 27 апреля 2010

Прежде всего, я предполагаю, что ваши звонки на printf должны отображать значения x, y и z или адреса из a, b и c, верно? В этом случае вам нужно изменить их на:

printf("%p\n", x);
printf("%p\n", y);
printf("%p\n", z);

Они будут учитывать размер указателя на вашем процессоре, если он отличается от размера int. Они также будут печатать адрес в шестнадцатеричном формате, что гораздо более распространено, поскольку адреса могут быть довольно большими.

и после увеличения значение указателя равно 65526 ​​(как 2 приращение для целого)

Предполагается, что вы находитесь на платформе, где int равен 2 байтам (на большинстве современных домашних ПК int сейчас, вероятно, равен 4).

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

Вы на самом деле не разыграли ни одного из указателей здесь. Таким образом, память, занятая a, b и c, остается нетронутой; все, что вы сделали, изменили то, на что указывают x, y и z. Если бы вы стали разыменовывать один из указателей после его увеличения, вы бы изменили память после переменной, на которую она первоначально указала. Таким образом, если a находится по адресу 65526 ​​десятичного и int 2 байта:

int *x = &a; // x points to the integer at "65526" (a)
x++;         // x points to the integer at "65528", a is still at 65526
*x = 5;      // you've just modified the memory at addresses 65528 and 65529.

Если 65528 или 65529 содержали некоторые другие важные данные (например, b или c), вы только что испортили состояние вашей программы.

1 голос
/ 27 апреля 2010

Если вы пытаетесь вывести значения указателей x, y и z, вам нужно изменить последние шесть операторов printf следующим образом:

printf("%p\n",x);

printf("%p\n",y);

printf("%p\n",z);

x++;

y++;

z++;

printf("%p\n",x);

printf("%p\n",y);

printf("%p\n",z);

Распечатав их таким образом, вы напечатаете их адреса, и вы должны увидеть их изменение после увеличения их.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...