2017-02-06 2 views
0
#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    float *pf; 
    float m[][3]={ 
     {0.1, 0.2, 0.3}, 
     {0.4, 0.5, 0.6}, 
     {0.7, 0.8, 0.9} 
    }; 
    printf("%d \n",sizeof(m)); 
    pf=m[1]; 
    printf("%f %f %f \n",*pf, *(pf+1), *(pf+2)); 
    printf("%f %f %f \n",*pf, *(pf++), *(pf++)); 
} 

Я действительно понимаю вывод второй последней печатиf. Пожалуйста, поправьте меня, если я ошибаюсь. указатель pf хранит адрес первого элемента m [1]. * pf переходит к этому первому элементу и выдает значения 0.4, * (pf + 1) и переходит к следующим элементам, адресует и выводит этот элемент и т. д. То, что я не получаю, является последним printf. Не должно быть подобного. Предположим, что в последнем printf * pf отправляется адрес, сохраненный в pf (который аналогичен первому элементу m [1]), поэтому выход должен быть 0,4, но вместо этого выход равен 0,6. Для * (pf ++) следует увеличивать до следующего элемента и выводить второй элемент, т. Е. 0,5 и последний один * (pf ++) также должен выводить 0,5, а вместо этого выводить 0.4. Пожалуйста, объясните, что я действительно смущен.указатели увеличиваются на 1,2,3 или приращение приращения в массиве

+0

Размеры массива сообщаются в байтах, а не в количестве записей. Ваш (двойной) массив имеет 9 записей по 4 байта каждый. – kaylum

+3

Чтобы получить число записей в массиве 'm', используйте' sizeof (m)/sizeof (* m) '. –

+0

«* Я действительно смущен. *», Но не из-за указателей, а потому, что вы, похоже, не понимаете, как работает «++» -оператор. Читайте об этом и возвращайтесь к более простому примеру, просто используя 'int', без массивов, без указателей. – alk

ответ

1

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

*pf, *(pf++), *(pf++) 
3rd 2nd  1st 
  1. Второй *(pf++) оценивается первым. pf указывает на 0,4, это значение выражения, а затем pf увеличивается.

  2. Первый *(pf++) оценивается вторым. pf указывает на 0,5, это значение выражения, а затем pf увеличивается.

  3. *pf оценивается третьим. pf указывает на 0,6.

  4. В printf() печатает

    0.6 0.5 0.4 
    

Ваш код является классическим примером неопределенного поведения.

+0

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

+0

, так что невозможно предсказать вывод таких утверждений? – peace9000

+0

@ peace9000: Нет, нет. Вы избегаете конструкций, где значительным является порядок оценки аргументов функции или порядок оценки операндов оператора. – AlexP

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