Y не увеличивается - PullRequest
       3

Y не увеличивается

1 голос
/ 29 марта 2011

Это программа:

#include<stdio.h>  

void main() {
    int *x,*y;
    int a=23,b=56;

    x=&a;
    y=&b;

    printf("%d\t%d",x,y);

    x++;
    y++;

    /* here only x is incremented but y remains same. What is the reason? */
    printf("\n%d\t%d",x,y);
}

т.е. x увеличивается на 2. Но y остается без изменений. Как?

Ответы [ 6 ]

11 голосов
/ 29 марта 2011

Существует нет гарантии того, что ваши указатели имеют тот же размер, что и ваши целые числа, поэтому вам не следует использовать %d в качестве спецификатора формата.

Я видел проблемыаналогично этому, когда люди передают long переменные в printf со спецификатором для int.Так как long был шире int, это сбило с толку printf относительно того, где что-то было в стеке.

Вы должны использовать %p для указателей.Есть также множество других проблем с этим кодом, в соответствии со стандартами.Попробуйте в качестве отправной точки следующее:

#include <stdio.h>

int main (void) {
    int *x, *y;
    int a = 23, b = 56;

    x=&a; y=&b;
    printf ("%p  %p\n", x, y);

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

    return 0;
}

Вот одно возможное объяснение (благодаря комментарию от Майкла Берра):

Допустим, ваш указатель32-битные, а ваши целые 16-битные и что вы используете архитектуру с прямым порядком байтов (например, Intel).

Далее, предположим, что адрес a равен 0x12345678, а адрес bis 0x1234567a.

Когда вы передаете их в printf, вы помещаете два 32-битных значения в стек, но printf считывает только два 16-битных значения, так как было сказано, что с %d %d спецификаторы формата:

       himem
      --------
    / | 0x12 |
push  | 0x34 |
   |  | 0x56 |
    \ | 0x78 |
      --------
    / | 0x12 | \ printf reads 0x1234
push  | 0x34 | /
   |  | 0x56 | \ printf reads 0x567a
    \ | 0x7a | /
      --------
       lomem

Затем, когда вы увеличиваете оба указателя и снова вызываете printf, вы получаете:

       himem
      --------
    / | 0x12 |
push  | 0x34 |
   |  | 0x56 |
    \ | 0x7a |
      --------
    / | 0x12 | \ printf reads 0x1234
push  | 0x34 | /
   |  | 0x56 | \ printf reads 0x567c
    \ | 0x7c | /
      --------
       lomem

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

0 голосов
/ 29 марта 2011

Пожалуйста, программа:

#include<stdio.h>
void main() {
    int *x= NULL;
    int *y = NULL;
    int a=23,b=56;
    x=&a;
    y=&b;
    printf("%x\t%x",x,y);
    x++;
    y++;
    printf("\n%x\t%x",x,y);
}

Я полагаю, что все должно быть в порядке. Только значения правильно инициализированы.

0 голосов
/ 29 марта 2011

вы увеличиваете указатели , а не значения, если это поможет.

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

#include<stdio.h>
int main(int argc, char *argv[]) {
        int *x,*y;
        int a=23,b=56;
        x=&a;
        y=&b;
        printf("%d\t\t%d",*x,*y);
        x++;
        y++;
        printf("\n%d\t\t%d",*x,*y);
        return 0;
}

, который скомпилируется и покажет содержимое моего компилятора, что приведет к следующему выводу:

23      56
1606415920      23

(я ставлю два '\ t' на строку, чтобы гарантировать разделение значений, это не влияет на остальную часть кода)

, поскольку я предполагаю, что вы хотите увеличить код a, а b код будет выглядеть следующим образом:

#include<stdio.h>
int main(int argc, char *argv[]) {
        int *x,*y;
        int a=23,b=56;
        x=&a;
        y=&b;
        printf("%d\t\t%d",*x,*y);
        (*x)++;
        (*y)++;
        printf("\n%d\t\t%d",*x,*y);
        return 0;
}

который печатает:

23      56
24      57
0 голосов
/ 29 марта 2011

В вашем коде вы обращаетесь к указателю и увеличиваете указатель. Что вы, возможно, хотели бы сделать, это:

void main() {
  int *x,*y;
  int a=23,b=56;
  x=&a;
  y=&b;
  printf("%d\t%d",*x,*y);
  (*x)++;
  (*y)++;
  printf("\n%d\t%d",*x,*y);
  return 0;
}

Обратите внимание на (* x) ++ и (* y) ++ для доступа к значению указателя, потому что именно это вы хотите увеличить. Если вы пишете x ++ или y ++, вы увеличиваете сам указатель, что означает, что вы помещаете адрес, на который он указывает, вперед. Это приводит в вашем случае к неопределенным значениям.

0 голосов
/ 29 марта 2011

Привет, вы увеличиваете адрес указателя, а не значение, используйте (*x)++ (*y)++

0 голосов
/ 29 марта 2011

как насчет ... int * x;int * y;вместо int * x, * y;

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