Применение указателей в массиве C

Я точно записываю ниже код, и он должен выдавать «2036, 2036, 2036», но он продолжает возвращать 8-9 цифр странного случайного значения всякий раз, когда я несколько раз нажимаю кнопку «Выполнить».

Кто-нибудь знает об этом?

 #include <stdio.h>
 int main() 
  { 
  unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6}, 
                       {7, 8, 9}, {10, 11, 12}};
  printf("%u, %u, %u", x+3, *(x+3), *(x+2)+3);
  } 

Как вы думаете, почему ожидаемый результат должен быть «2036, 2036, 2036»?

Irelia 10.04.2022 14:04
x есть. двумерный массив, что такое *(x+3) по вашему мнению?
Cheatah 10.04.2022 14:04
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
2
28
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы объявили двумерный массив

unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6}, 
                        {7, 8, 9}, {10, 11, 12}};

Используется в выражениях аргументов при вызове pf printf

printf("%u, %u, %u", x+3, *(x+3), *(x+2)+3);

он неявно преобразуется в указатель на свой первый элемент типа unsigned int ( * )[3].

Итак, x + 3 — это указатель на четвертую строку массива, которую вы пытаетесь вывести как беззнаковое целое число, что приводит к неопределенному поведению.

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

Выражение *(x+2) дает первый элемент третьей строки, как описано выше. Таким образом, выражение *(x+2)+3 дает адрес памяти после последнего элемента третьей строки.

Просто перепишите призыв printf лайка

printf("%p, %u, %u\n", ( void * )( x+3 ), **(x+3), **(x+2)+3);

И вы получите адрес четвертой строки, значение первого элемента четвертой строки (10) и значение первого элемента третьей строки (7) плюс 3, что равно 10.

В противном случае вам нужно написать

printf("%p, %p, %p\n", ( void * )( x+3 ), ( void * )( *(x+3) ), ( void * )( *(x+2)+3 ) );

для вывода исходного выражения, имеющего типы указателей.

Разве не будет *(*(x+2)+3)?

Irelia 10.04.2022 14:07

Однако Я не понимаю поведения, которое вы описываете.**(x+3) работает.

Robert Harvey 10.04.2022 14:08

@Ирелия, прости. Я был невнимателен. :)

Vlad from Moscow 10.04.2022 14:16

@MisoKorea Либо используйте printf("%p,%u,%u\n", (void *)(x+3), **(x+3), **(x+2)+3); и на выходе будет некоторый адрес, 10, 10. Или это printf("%p, %p, %p\n", (void *)( x+3), (void *)( *(x+3) ), ( void * )( *(x+2)+3 ) ); а вывод будет состоять из трех адресов. Тот же результат вы получите в визуальной студии.

Vlad from Moscow 10.04.2022 14:54

Спасибо за все ваши отзывы! Я добавил "printf("%p, %p, %p\n", (void *)( x+3), (void *)( *(x+3)), (void *)( *(x+ 2)+3 ) )";, но, к сожалению.. это не работает с моим визуальным кодом.. как вы думаете, это проблема компилятора..? Это дает такие ответы, как "000000393b1ff8d4, 000000393b1ff8d4, 000000393b1ff8d4"

Miso Korea 10.04.2022 14:55

Я думал, что результат должен быть «2036, 2036, 2036», и моя логика такова. 2D-массив состоит из нескольких 1D-массивов. И выше 2D-массив состоит из 4 наборов 1D-массива, каждый из которых имеет 3 элемента. 1) Итак, x+3 возвращает «2036», так как указатель указывает адрес для 1-го элемента 4-го 2D-массива. 2) *(x+3) возвращает "2036", поскольку это означает адрес 1-го элемента 4-го массива 1D (которые принадлежат 4-му массиву 2D). 3) *(x+2)+3 возвращает "2036", поскольку это означает адрес 1-го элемента 4-го массива 1D. (которые принадлежат 4-му 2D-массиву).

Miso Korea 10.04.2022 14:58

@VladfromMoscow Спасибо за вашу поддержку!! теперь он работает с "printf("%p, %u, %u\n", ( void * )( x+3 ), **(x+3), **(x+2)+3); " и возвращает "0000007c949ff904, 10, 10". Но почему он возвращает "000000b5f07ff954, 4034918740, 4034918740", если я набираю в коде только одну звездочку "printf("%p, %u, %u\n", (void *)( x+3), *(x+ 3), *(х+2)+3);" вместо "000000b5f07ff954, 2036, 2036"

Miso Korea 10.04.2022 15:10

@MisoKorea Как я указал в ответе, выводятся адреса как объекты типа unsigned int, что приводит к неопределенному поведению.

Vlad from Moscow 10.04.2022 15:12

@MisoKorea Если ответ разрешил вашу путаницу в отношении указателей и массивов, то, чтобы закрыть вопрос, выберите лучший ответ. В этом случае ваша репутация будет повышена. :)

Vlad from Moscow 10.04.2022 18:19

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

Miso Korea 10.04.2022 20:28

@MisoKorea Спасибо. Вы все сделали правильно. :)

Vlad from Moscow 10.04.2022 20:28

Другие вопросы по теме