2011-12-14 7 views
0
#include <stdio.h> 

int main(void) { 
    int a[5], *p, i; 
    p = a; 
    p = (int []){1, 2, 3, 4, 5}; 
    for (i = 0; i < 5; i++, p++) { 
     printf("%d == %d\n", *p, a[i]); 
    } 
    return 0; 
} 

И вот (YMMV):присвоение сложного литерала указателю массива дает как ожидаемый результат, так и мусор в одном и том же месте и времени?

$ gcc -O -Wall -Wextra -pedantic -std=c99 -o test test.c; ./test 
1 == -1344503075 
2 == 32767 
3 == 4195733 
4 == 0 
5 == 15774429 

Печать массива с помощью арифметики указателей показывает, что это действительно имеет место целочисленного последовательность от 1 до 5, но печать еще раз, что, предположительно, тот же массив выражается через индексы дает неинициализированное дерьмо. Зачем?

+2

Я понимаю, что это всего лишь демо-код, но никогда не пишите 'int a [5], * p, i;' в реальной жизни! –

ответ

4

Вы назначаете только p, никогда не a, поэтому a никогда не инициализируется.

int a[5], *p, i; 
// a uninitialized, p uninitialized 
p = a; 
// a uninitialized, p points to a 
p = (int []){1, 2, 3, 4, 5}; 
// a uninitialized, p points to {1, 2, 3, 4, 5} 
+0

Arggggh. Да спасибо. 2am синдром. – Will

0

Вы назначаете указатель на массив, вы не копируете данные в массив. Таким образом, вы получаете данные из одного источника и мусора из другого.

2

Вы никогда не инициализируете элементы a. Оба присваивания p изменить, где p баллов; ни одно присвоение ничего не делает до a или его элементов.

1

присваивается значение a для p, а затем сразу переопределить его со значением другого массива целых чисел. В printf("%d == %d\n", *p, a[i])*p и a[i] больше не ссылаются на одно и то же место в памяти, а a остается неинициализированным (отсюда мусор).

0

Ваш код эквивалентен следующему:

int a[5]; 
int b[5] = { 1, 2, 3, 4, 5 }; 

for (i = 0; i < 5; i++) 
    printf("%d == %d\n", b[i], a[i]); 

С a не инициализирован, вы получите непредсказуемые значения (на самом деле это не определено поведение даже читать эти переменные).