2016-06-19 2 views
1
#include<stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    printf("%s\n", &str+2); 
    printf("%p\n",&str); 
    printf("%p\n",&str+2); 
    return 0; 
} 

Программа выше мигает ошибка на линии 6 поговорке:разница между полукокса * и полукокса (*) [25]

warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[25]’ [-Wformat=] 

Интересно, что разница между этими двумя. На выходе всегда отображаются два адреса с разницей в 32 байта. Я ожидал выход с разницей в 2, поскольку я пытаюсь напечатать адрес str и адрес str +2. Вы можете объяснить?

+0

удалить '&' ..... –

+0

да! Небольшой поиск сказал мне об этом. Но в чем ошибка в программе? –

+0

Некоторая информация: http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499 –

ответ

0

После небольшого исследования я придумал это объяснение. &str+2 рассматривается как указатель на массив. char (*)[25] говорит, что это указатель на символьный массив размера 25. Чтобы найти объяснить, почему выход показывает 32 разницу байт Я снова выполнил программу и замечает, выход был показан в шестнадцатеричном т.е.

0x7ffd865b2710 
0x7ffd865b2742 

При преобразовании в base 10, он становится разницей в 50 байт, которая является указателем на массив, который находится на втором месте для текущего массива (помните & str + 2). Чтобы сделать это более понятным, вот небольшая диаграмма памяти.

&str -----> current array ie str. array is 25 bytes long. 
&str+1 -----> array lies after 1 position to current array. This address is 25 bytes away from &str. 
&str+2-----> array lies after 2 position to current array. This address is 50 bytes away from &str. 
0

EDIT: после OP добавил новую строку 6.

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

#include <stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    printf("%s\n", str+2); 
    printf("%p\n", (void*)str); 
    printf("%p\n", (void*)(str+2)); 
    return 0; 
} 

выход программы:

llo World 
0018FF20 
0018FF22 

EDIT 2: Это показывает эффект прохождения указатель массива. Компилятор считает, что вы обращаетесь к третьему элементу массива строк каждого размера 25. Я умудрился показать, как это неопределенное поведение действительно проявилось.

#include <stdio.h> 

int main() 
{ 
    char str[25] = "Hello World"; 
    char abc[] = "abcdefghijklmnopqrstuvwxyz"; 
    printf("%s\n", &str+2); 
    return 0; 
} 

выход программы:

wxyz 
+0

В этом вопросе возникает вопрос об объяснении. Но вам лучше искать dup ... –

+0

Вы хотите объяснить синтаксическую ошибку? Я сделал это, указав правильный синтаксис. –

+0

@WeatherVane: В чем была проблема с моей программой? Я хочу знать причину, почему компилятор поднял ошибку. Спасибо за правильный ответ. –

3

Разница в этих двух случаях довольно просто. Предположим, что у нас есть массив из 25 символов: char arr[25];. По условному выражению arr оценивается указателем на первый элемент массива, то есть arr является таким же, как &arr[0]. Обратите внимание, что здесь унарный оператор & применяется к lvalue arr[0], который имеет тип char. И как результат & дает выражение с типом char * (т.е. указателя на char)

Когда мы говорим &arr - именующий является arr, то есть char [25] (т.е. массив из 25 символов). И как результат, все выражение имеет тип char (*)[25] (то есть указатель на массив из 25 символов). Итак, у нас есть выражение с совершенно другим типом, который несовместим с char *.

Немного примечаний об индексировании. Разница между &arr + 2 и &arr составляет 50 байт (0x32 в шестнадцатеричном формате), так как sizeof(arr) == 25.

1

char * является указателем на char в то время как char (*)[25] является указателем на массив из 25-х char так что эти типы отличаются и компилятор по праву выдает предупреждение.

Кроме того, поскольку &str является адрес str массива и имеет тип char (*)[25], значение &str+2 будет равна:

&str + 2*sizeof(char (*)[25]) = &str + 2*25 = &str + 50 = &str + 0x32 

Так как указатель увеличивается в соответствии с типом он указывает.

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