2010-09-03 3 views
9

Ниже приведены 2 программыпочему разные ответы?

Первые

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    int *p; 
    p=&a; 
    printf("%u %u",p,p+1); 
} 

Второй

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    printf("%u %u",&a,&a+1); 
} 

Теперь в двух programs..I напечатали значения & А с использованием р в первом код и непосредственно во втором.

Почему результаты разные?

ответ я получаю.

for first 3219048884 3219048888 
for second 3219048884 3219048904 
+1

Не могли бы вы форматировать ваши строки коды с помощью кнопки коды в редакторе? Это облегчает людям помощь. – jlafay

+2

Каковы результаты, которые вы получаете? –

+2

И каковы результаты, которые вы видите? –

ответ

14

Тип &a: int (*) [5]. Поэтому &a+1 является указателем, который равен 5 int s далее, чем a. Однако тип p составляет int *, поэтому p+1 является указателем, который равен 1 int далее, чем p.

+0

Sneaky! Я одобряю. –

+0

Да, но это не относится к вопросу, за исключением последнего значения серии – kriss

+1

@kriss: Как это неуместно? Это последнее значение в каждой последовательности отличается, и именно поэтому. –

-2

Вы должны использовать p = a и не p = &a. Массив, такой как a, уже считается постоянным указателем. Вам не нужно разыгрывать его с помощью оператора &.

+0

'a' не является указателем. Никогда. – GManNickG

+0

@GMan Почему тогда вы можете сказать '* a = 2' с тем же значением, что и' a [0] = 2'? – Frank

+0

Поскольку массивы имеют неявное преобразование в указатель. Но массивы не являются указателями. – GManNickG

2

В обеих программах вы печатаете адреса памяти массива.

Это может варьироваться при каждом запуске программы. Память, которую ОС хочет вам дать, может быть разной.

Когда ваша программа объявляет массив из 5 целых чисел, ОС обещает дать вам 5 последовательных целых чисел, она НЕ обещает, какую память вы получите, или что вы будете получать одну и ту же память каждый раз.

7

Когда я бегу, я получаю это:

1245036 1245040 1245036 1245040 
1245036 1245040 1245036 1245056 

с той лишь разницей, в последней позиции, p+1 против &a+1

p является указателем на целое число, так p+1 это адрес следующего целого числа. (т. е. еще 4 байта в памяти)

a представляет собой массив из 5 целых чисел, поэтому & a + 1 является адресом следующего массива из 5 целых чисел. (т. е. еще 20 байт в памяти)

1

Ваша первая программа недействительна. Нельзя назначать p = &a, так как p имеет тип int * и &a имеет тип int (*)[5]. Эти типы несовместимы. Если ваш компилятор достаточно свободен для разрешения такого рода присвоений (он хотя бы предупредил вас?), Он, вероятно, интерпретировал его как p = (int *) &a, т. Е. Он принудительно переинтерпретирует значение &a в качестве указателя int *. Таким образом, вся арифметика указателя в вашей первой программе - int * арифметика. Вот почему первая программа производит тот же вывод для значений a+1 и p+1.

Во второй программе значение &a не переинтерпретировано. Он сохраняет свой оригинальный тип `` int () [5] and it follows the rules of normal pointer arithmetic for type int () [5] , meaning that when you do & a + 1 , the pointer is moved sizeof (int [5]) `bytes, как и должно быть. Вот почему результат отличается от первой программы.

2

У вас есть две программы с разными кадрами стека, не удивительно, что адреса локальных переменных разные. Il может меняться каждый раз, когда вы запускаете программу (это то, что она делает, когда я пытаюсь это сделать, код, скомпилированный с помощью gcc в Linux).

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

#include<stdio.h> 

void main() 
{ 
    int a[5]={1,2,3,4,5}; 
    int *p; 
    p=&a; 
    printf("%u %u %u %u ",a,a+1,p,p+1); 
    printf("%u %u %u %u",a,a+1,&a,&a+1); 
} 

Для (достаточно) полного объяснения разницы между указателями и массивами вы можете посмотреть на мой ответ here

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