powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / K&R Многомерные массивы
66 сообщений из 66, показаны все 3 страниц
K&R Многомерные массивы
    #38551348
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Сегодня изучал многомерные массивы. У меня возникла первая часть вопросов связанных с примером приведённым в главе.

Привожу код, несколько изменён в связи с индексацией предложенной в книге
Предварительные комментарии.
Функция day_of_year возвращает порядковый номер дня по номеру месяца и дня.
Функция month_day неявно возвращает день и номер месяца по году и порядковому номеру.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
#include "stdafx.h"

static int day_tb[2][13] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; /*0*/
int day_of_year(int y, int m, int d)
{
	int i, leap;/*2.2*/
	leap = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;/*1*/
	for (i = 0; i < m-1; ++i)
	{
		d += day_tb[leap][i];// к дате прибавляется количество дней в предыдущих месяцах.
	}
	return d;
}

void month_day(int y, int yd, int* pd, int* pm)
{
	//Ниже мой код, а не K&R
	int i = 0, leap;/*2.1*/
	leap = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
	while (yd>day_tb[leap][i])/*3.1*/
	{
		//yd = ((yd - day_tb[leap][i]) > day_tb[leap][i + 1] && i <= 10) ? yd - day_tb[leap][i] : yd;/*4*/
		yd -= day_tb[leap][i];/*5.1*/
		i++;/*5.2*/
	}
	*pd = yd;
	*pm = ++i;

	//Код K&R
	/*3.2
	for (i = 0; yd > day_tb[leap][i];i++) 
	{
		...то-же что и у меня
	}
	... */
}

int _tmain(int argc, _TCHAR* argv[])
{
	printf("%i \n", day_of_year(2013, 2, 6));
	int d, m;
	month_day(2013, 37, &d, &m);
	printf("%i %i \n",d,m );
	return 0;
}



0
K&Rмы поместили в начало массива day_tab столбец из нулей для того, чтобы номера месяцев изменялись естественным образом от 1 до 12, а не от 0 до 11. Так как за экономию памяти у нас пока не награждают, такой способ проще чем подгонка индексов.

Мне кажется если человек понял что такое указатель, то математического аппарата для индексации хватит. Это только усложняет, на мой взгляд, нужно изменить этот код в последующих изданиях, я их к сожалению не видел. Может уже изменили. Но больше меня удивила фраза про экономию памяти. Я вообще в шоке от нее. Это сейчас я могу добавить этот вектор-столбец без проблем, но раньше ?Экономия памяти была особенно актуальна. Этот столбец я убрал тут, изменил немного индексацию, и все дела .
Попутно: подскажите пожалуйста, как мне посмотреть все байты онлайн, где хранятся все элементы мои массива и тп. То есть как наблюдать за всей памятью выделенной для программы ОС онлайн. Какое-то средство при дебаге наверняка есть ? использую VS Express 2013 for Desktop

1
Для меня это выглядит как x ^ y v z, где ^ конъюнкция а v дизъюнкция. Но как это будет работать ?? ну я догадываюсь что 0^1v0 вернёт 0 например, и эта схема работает подобным образом. Верно ведь ? но почему способ определения высокосного года не year%4?

2.1-2.2
Лучше вынести в качестве глобальных переменных ? Почему да или нет ?

3.1-3.2
Ну while ведь очевидней, код второй функции я написал не смотря на то, какой код приведён и Ритчи и Кернигана, но когда увидел for, был удивлён, ведь это жутко нелогично делать тут for, очевидно это while ! Хотя for и while это одно и то-же, это я понимаю. Или в этом своя фишка которую я не понимаю ? Как вы бы поступили в таком случае ?

4
Как организовать блок 3.1/3.2 подобным образом ? Ну очень нравятся такие конструкции, жутко красивые :p

5.1-5.2
Мне уже хочется написать yd -= day_tb[leap][i++] , но правильно ли так ? На 100 ли процентов компилятор проведёт инкремент вторым действием ?? на всех машинах ? во всех ос ? Возникнет ли в данном случае неудачный пример побочного эффекта по K&R ?
Да и вообще такой код мне кажется красивым, как while(*a==*b) в коде где идёт лексографическое сравнение строк(именно там, а не где его приводят K&R), но для меня очевидно, что начинающий программист который в дальнейшем будет читать мой код, может это не понять и запутаться. Ответьте на этот вопрос, и скажите как вы сами предпочитаете делать ?

Пример изначально показался скучным( в который раз), но в итоге понравился ( в который раз такое)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551354
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0 - хватит. Но это же учебник. Для простоты изложения и чтобы лишний раз напомнить ученику что массивы начинаются с нуля... Ради этого можно и потерпеть разок избыточность. Пусть ученик сам увидит что значит начинать массивы с единицы.

1 - потому что кое-кто не знает как определяется високосный год. Угадай кто этот "кое-кто"?

2 - А зачем эти переменные в виде глобальных? Не, ну можно конечно если так хочется. Вынеси и попытайся теперь запустить любую из этих функций в цикле:
Код: plaintext
1.
2.
 for(i=0; i<10; i++) 
   printf(%d\n", day_of_year(2014, 2, i);



3 - без разницы. for в таких случаях удобен тем, что инициализация и приращение переменной цикла идет рядышком с проверкой условия цикла. while - в какой-то степени чуть более логичен если принять что в for обязательно надо проверять саму переменную а не что-то основанное на ней.
А что выбирать - личные предпочтения.

4 - не понял вопроса. Какой блок ты хочешь так организовать? А вообще строка 4 ужастна. Длинная и закрученная. Чтобы ее понять, ее надо читать. Беглому взгляду не доступна.

5. Читай учебник (тот самый) внимательнее. Постфиксные инкременты описаны в книге.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551361
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
K&RМассив day_tab является первым двухмерным массивом с которым мы имеем дело. По определению в С двухмерный массив по существу является одномерным массивом, каждый элемент которого является массивом. Поэтому индексы записываются как

Код: plaintext
1.
2.
3.
day_tab[i][j]
а не
day_tab[i,j]


По мне так раз по существу n-мерные массивы одномерны, то запись вторая была бы логична. Некоторый аналог сложной индексации внутри массива.
Вопрос: Фраза выделенная красным подразумевает что элементы в памяти расположены друг за другом ? Вот мой тест:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 11; j++)
		{
			printf("%i %p \n", day_tb[i][j], &day_tb[i][j]);
		}
		printf("\n");
	}


а что делает мой 060 ? Скрин прикрепил, но не понял отобразится он туту или нет сразу
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551380
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробую вывести значения двухмерного массива через указатели как будто бы работаю с линейным массивом

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
for (int i = 0; i < 20;i++)
	{	
		if (*(day_tb + i) == '\0')
		{
			break;
		}
		else
		{
			printf("%i \n", *(day_tb + i));
		}
	}



Этот код идёт по подмассивам массива ? и причём он никогда не остановится, потому не while
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551385
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Окей, я понял что не всё так просто как говорят Керниган и Ритчи, и я сделал так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	int i = 0;
	int* pday_tb = &day_tb[0][0];
	while (*(pday_tb+i)!='\0')
	{
		printf("%i \n", *(pday_tb+i));
		++i;
	}



Но, почему у меня на экране только один массив ? где весь ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551389
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть он нашёл нуль внутреннего подмассива и остановился, вероятно всего так, и на 060 этот нуль как раз и находится, теперь нужно понять почему так, почему для записи с именем массива и в цикле while (*(pday_tb+i)!='\0')
компилятор не понимает где конец именно этого двухмерного массива
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551403
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl, спасибо.

Я прочитал, и в нём расхождение. Потому в мою голову и закрались сомнения. Сначала должно быть использовано значение и потом будет инкремент. Но, на страницах 56-57, где как раз рассказывается про побочный эффект, написано:
K&R...примером типичной неудачной ситуации является оператор
Код: plaintext
1.
A[i]=i++;


Возникает вопрос, старое или новое значение i служит в качестве индекса. Компилятор может поступать разными способами, и в зависимости от своей интерпретации выдавать разные результаты...
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551414
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryТо есть он нашёл нуль внутреннего подмассива и остановился, вероятно всего так
это так потому что ты так написал
'\0' значит 1 байт с кодом символа 0. т.е. просто ноль.

SashaMercury компилятор не понимает где конец именно этого двухмерного массива
Компилятор не должен ничего понимать. Ты объявил массив из 2 строк по 13 элементов, а проинициализировал 12 , вот компилятор туда и вставил 0 вместо недостающих. Т.е. реально получилось так:
Код: plaintext
1.
2.
static int day_tb[2][13] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}, 
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0} };



PS у массива нет "конца" как ты ожидаешь, ты должен сам следить в коде чтобы не выйти за пределы массива.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551425
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот я дошёл до самой главной фразы в этой главе, видимо они больше всего относится к описанию 2хмерных массивов:
K&RЕсли двумерный массив передается функции, то описание соответствующего аргумента функции должно содержать количество столбцов; количество строк несущественно, поскольку, как и прежде, фактически передается указатель.


те я могу написать на выбор:
Код: plaintext
1.
2.
3.
4.
5.
6.
void smth_func1(int array[2][13])
{}
void smth_func2(int array[][13])
{}
void smth_func3(int(*array)[13])
{}



Судя по тому что я привёл выше из K&R, я понял что в функцию я передаю не двухмерный массив, а блок на 13 элементов(во втором и третьем случае).
Мне хочется передавать только указатель на array, и всё, а дальше вертеть им как хочу. Это возможно ? Правильно ли так рассуждать ? Как делаете вы ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551426
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВопрос: Фраза выделенная красным подразумевает что элементы в памяти расположены друг за другом ? Вот мой тест:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
	for (int i = 0; i <= 1; i++)
	{
		for (int j = 0; j <= 11; j++)
		{
			printf("%i %p \n", day_tb[i][j], &day_tb[i][j]);
		}
		printf("\n");
	}


а что делает мой 060 ? Скрин прикрепил, но не понял отобразится он туту или нет сразу
Та же ошибка. 13 элементов а не 12.
Пиши < вместо <=, тогда код понятнее будет
Код: plaintext
1.
2.
3.
for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 13; j++)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551429
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, спасибо C:

Заработало, это я исправлял индексацию, убрал лишние нули, и забыл уменьшить размер массива (
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551432
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TТа же ошибка. 13 элементов а не 12.
Пиши < вместо <=, тогда код понятнее будет


дада, уже понял ( невнимательно изменил пример из K&R ((
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551436
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TТа же ошибка. 13 элементов а не 12.
Пиши < вместо <=, тогда код понятнее будет



Спасибо за совет C:
Индексация мне ясна , что <= что <, все ошибки пошли от размерности массива (
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551449
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury...
Мне хочется передавать только указатель на array, и всё, а дальше вертеть им как хочу. Это возможно ? Правильно ли так рассуждать ? Как делаете вы ?
Учти что указатель дает только адрес в памяти где массив начинается, а где его конец будет неизвестно.

Массив это просто непрерывный кусок памяти. Адресация в памяти линейна, поэтому любой N-мерный массив хранится как одномерный. Например если ты делаешь массив int[2][13] то выделяется 4*2*13 байт.
Обращение к элементу массива это расчет адреса его хранения относительно начала. Например *a[1][6] это *a[0][0] + 1*13 + 6

Многомерными массивами не пользуюсь (не требуется), а с одномерными обычно практика такая: передается указатель на начало и размер массива (количество элементов, а не байт).
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551451
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запусти
Код: plaintext
1.
2.
	printf("day_tb[1][3] = %d %p\n", day_tb[1][3], &day_tb[1][3]);
	printf("day_tb[0][16] = %d %p\n", day_tb[0][16], &day_tb[0][16]);


это для массива day_tb[2][13]
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551458
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_T,
Вывел 16 и 17 элементы массива. Это здорово !)Сплошная индексация, или..мм. какое бы слово подобрать. Сквозная индексация, так лучше ? Или, сквозная относительная индексация. Мне нравится это свойство массивов на С
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38551480
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По сути получение элемента a[i][j] массива a[N][M] сводится к расчету указателя на этот элемент pa = &a[0][0] + i * M + j
Проверок на выход за границы массива не делается.
в твоем примере 1*13 + 3 = 0*13 + 16

Главный минус использования в коде записи типа a[i][j] в потере производительности, т.к. умножение достаточно тяжелая операция для процессора. Быстрее работает если использовать указатели и сложение/вычитание для их изменения.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552722
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_T, спасибо С:
Я понял, в целом.

Про високосные года, нашёл информацию, может быть кому-нибудь пригодится
http://ru.wikipedia.org/
По-прежнему високосным оставался год, номер которого кратен четырём, но исключение делалось для тех, которые были кратны 100. Отныне такие годы были високосными только тогда, когда делились ещё и на 400.

Иными словами, год является високосным в двух случаях: либо он кратен 4, но при этом не кратен 100, либо кратен 400. Год не является високосным, если он не кратен 4, либо он кратен 100, но при этом не кратен 400.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552756
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Экспериментировал сегодня. Исходя из того какая логика накладывается на n-мерные массивы f e :day_tb[1][3], day_tb[0][16], ожидал аналогичное на одномерные, но не получил то что хотел.
Два вопроса:
1.
Код: plaintext
1.
2.
	int test[2][13] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } };
	printf("%i %i", test[16], test[1][3]);


На что указывает test[16]? У меня отобразилось число порядка миллиона, вместо ожидаемой 3.

2. Почему нельзя обратиться к одномерному массиву таким образом : ar[1][2] ? Исходя из общей логики массивов на С это ожидалось
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552767
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury1.
Код: plaintext
1.
2.
	int test[2][13] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } };
	printf("%i %i", test[16], test[1][3]);


На что указывает test[16]? У меня отобразилось число порядка миллиона, вместо ожидаемой 3.
Если у вас test - это двухмерный массив, то test[16] - это одномерный массив, содержащий 16-ю (17-ю по порядку) строку test.
В данном случае - несуществующую строку, т.к. строк всего 2. Т.е. это выход за границы массива :)

Но миллион печатается не поэтому.
Т.к. test[16] - это одномерный массив, а ссылка на массив, при использовании в выражении, преобразуется в указатель 0-го элемента, то это выражение:
Код: plaintext
1.
printf("%i", test[16]);


эквивалентно такому
Код: plaintext
1.
printf("%i", (int)&test[16][0]);


Т.е. у вас печатается адрес приведенный к int.

SashaMercury2. Почему нельзя обратиться к одномерному массиву таким образом : ar[1][2] ? Исходя из общей логики массивов на С это ожидалось
Судя по всему у вас что-то не так с пониманием логики массивов на С :)
Во-первых так обратиться можно, если у вас одномерный массив указателей на что-то.

Во-вторых, если у вас в массиве не указатели, то конечно так обратиться нельзя. Потому что в С, к не-указателю нельзя применить операцию [].
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552778
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНа что указывает test[16]? У меня отобразилось число порядка миллиона, вместо ожидаемой 3.
Это указатель, вывелся адрес ячейки test[16][0]
т.е. test[16] это не 17й элемент массива, а указатель на начало 17-й строки
Код: plaintext
1.
2.
	printf("day_tb[1][0] = %d %p\n", day_tb[1][0], &day_tb[1][0]);
	printf("day_tb[1] = %d %p\n", *day_tb[1], day_tb[1]);



SashaMercury2. Почему нельзя обратиться к одномерному массиву таким образом : ar[1][2] ? Исходя из общей логики массивов на С это ожидалось
Неверно ты логику понял, нельзя ее трактовать в обратном направлении. Я выше писал
Dima TПо сути получение элемента a[i][j] массива a[N][M] сводится к расчету указателя на этот элемент pa = &a[0][0] + i * M + j
Если ты изначально объявил одномерный массив, то как компилятор узнает чему равно M ? например 12 элементов можно считать как [3][4], [4][3], [1][12] и т.д.

Если ты объявил массив двухмерным, то и работай с ним как с двухмерным. А то что можно указать индексы выходящие за пределы массива или перебрать указателем весь массив - это фича, которую надо знать и самому следить чтобы это случайно не происходило.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552780
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
вы мне что-то не договариваете, или в K&R не договаривают.
я не придавал значения операции []. это ключевая фраза. Нужно сначала понять её. Для меня a[x] это return *(a[0]+x). Но судя по вашим словам я неправильно её понимаю

И сейчас вы связали напрямую указатели и массивы. То о чём я раньше спорил

Anatoly MoskovskyВо-вторых, если у вас в массиве не указатели, то конечно так обратиться нельзя. Потому что в С, к не-указателю нельзя применить операцию [].


Или вы выделили операцию [] отдельно.

В общем я слабо понял Вас. Наверное невнимательно что-то прочитал. Сейчас попробуй найти в книге что делает операция [].
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552789
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryДля меня a[x] это return *(a[0]+x).
Не, это неверно (Либо у вас опечатка)

Вот как компилятор это видит.
Допустим есть выражение
Код: plaintext
1.
a[x]


Так как "a" это ссылка на массив, то в выражении она заменяется на адрес 0-го элемента:
Код: plaintext
1.
(&a[0])[x]


С другой стороны выражение zzz[yyy] - это операция индексации []. Она заменяется на *(zzz + yyy).
Таким образом получаем:
Код: plaintext
1.
*(&a[0] + x)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552797
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Невнимательность (
Мне Dima_T объяснял это
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552798
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyТаким образом получаем:
Код: plaintext
1.
*(&a[0] + x)


Да, тут забыл еще одно преобразование, для устранения рекурсии определения [], через самого себя.

Адрес 0-го элемента &a[0] вычисляется так (element_type *)&a
(т.к. адрес массива и 0-го элемента совпадают в физическом представлении)

Т.е. итоговая формула такая:
Код: plaintext
1.
*((element_type *)&a + x)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552801
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Каким образов это ложное(в том смысле что по факту никакого приведения не происходит) приведение типов уводит от рекурсии через саму себя ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552809
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima_TЕсли ты изначально объявил одномерный массив, то как компилятор узнает чему равно M ?


Всё верно. Теперь понял логику )
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552819
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryКаким образов это ложное(в том смысле что по факту никакого приведения не происходит) приведение типов уводит от рекурсии через саму себя ?
Оно происходит. При компиляции.
Соответственно оно не ложное :)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552822
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Происходит приведение по типу int* к int *
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552829
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПроисходит приведение по типу int* к int *
Нет.
Код: plaintext
1.
2.
int a[1];
int* b = &a;  // разные типы - не откомпилируется
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552832
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
аа, верно.
ну да, имя массива это уже указатель
int a[1];
int* b=a;//так надо
а что я делаю когда пишу
int* b=&a;//я пытаюсь записать адрес по которому хранится адрес начала массива a ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552844
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryадрес по которому хранится адрес начала массива a
слишком много эпитетов.
проще надо говорить: указатель на массив :)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552867
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
int a[300];
int* b=a; // b разве не указатель на массив ?
сейчас b содержит адрес первого элемента массива ?? я ведь правильно понимаю ?

Я аж испугался что что-то не понимаю, проверил !
Код: plaintext
1.
2.
3.
4.
	int a[1];
	int* b = a;
	int* b1 = (int*)&a;
	printf("%p %p", b, b1);



Два абсолютно одинаковых адреса. Вы не до конца что-то мне говорите. Либо я что-то не знаю, а вы думаете что я знаю. Одно из двух на 100 процентов..


Код: plaintext
1.
int* b1 = (int*)&a;


И всё-таки, что тут происходит ?




Всем спасибо!
Всем хороших выходных C:

SS
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38552923
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryДва абсолютно одинаковых адреса. Вы не до конца что-то мне говорите. Либо я что-то не знаю, а вы думаете что я знаю. Одно из двух на 100 процентов..
Есть понятие "тип данных".
Один и то же набор байтиков может с точки зрения языка иметь совершенно разный смысл.
В данном случае
Код: plaintext
1.
2.
3.
4.
5.
6.
int a[1]; // массив, имеет тип: int [1] 
&a; // указатель на массив, имеет тип: int (*)[1]
int* b; // указатель на значение, тип  int*
b = a;  // компилятор неявно преобразует  из int [1] в int* (поскольку такое преобразование часть языка)
b = &a;  // компилятор не может неявно преобразовать  из int (*)[1] в int* 
         // поскольку такого неявного преобразования в языке нет
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38555180
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Anatoly Moskovsky
int a[1]; // массив, имеет тип: int [1]
&a; // указатель на массив, имеет тип: int (*)[1]
int* b; // указатель на значение, тип int*
b = a; // компилятор неявно преобразует из int [1] в int* (поскольку такое преобразование часть языка)
b = &a; // компилятор не может неявно преобразовать из int (*)[1] в int*
// поскольку такого неявного преобразования в языке нет


K&RОчевидно существует очень тесное соответствие между индексацией и арифметикой указателей. в действительности компилятор преобразует ссылку на массив в указатель на начало массива. В результате этого имя массива является
указательным выражением.

И теперь исходя из комментария от K&R ваша запись

b = &a;


Вообще не имеет никакого смысла. Исходя из того что я знаю.

Например запись

Код: plaintext
1.
2.
3.
4.
5.
b = &a[0][0]; 

OR

b=a;


ясны и несут очевидный смысл.

Когда мне может понадобиться

b = &a;


?

И

SashaMercuryКаким образов это приведение типов уводит от рекурсии через саму себя ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38555221
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИ теперь исходя из комментария от K&R ваша запись

b = &a;


Вообще не имеет никакого смысла. Исходя из того что я знаю.
Зачем вы мне это говорите, когда я выше написал
Код: plaintext
1.
int* b = &a;  // разные типы - не откомпилируется


Что непонятно в слове "не откомпилируется"?

SashaMercuryКаким образов это приведение типов уводит от рекурсии через саму себя ?
Формула вычисления элемента массива ссылалась на вычисление 0-го элемента - что является рекурсией (бесконечной). Чтобы устранить рекурсию, 0-й элемент вычисляется по-другому - приведением адреса массива.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38555239
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я перечитал ваше сообщение

Anatoly MoskovskyТаким образом получаем:
*(&a[0] + x)



Да, тут забыл еще одно преобразование, для устранения рекурсии определения [], через самого себя.

Адрес 0-го элемента &a[0] вычисляется так (element_type *)&a
(т.к. адрес массива и 0-го элемента совпадают в физическом представлении)

Т.е. итоговая формула такая:
*((element_type *)&a + x)



с учётом того что выв мне написали сегодня


Ооооо!!
Я понял, мне это нравится !!!! Я его полностью понял, от рекурсии до каждой скобки! Очень хорошее выражение, теперь мне оно очень нравится !)))
Мне кажется вместо всяких тестов на знание Си, можно показать это выражение ( и ещё плюс тот отличнейший пример от Дмитрия), и понять понимает ли человек язык хотя бы средне или нет
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556514
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сегодня с трудом заснул, думал про эту формулу. Насколько тут всё здорово.
Anatoly Moskovsky, а где вы это прочитали ? Что компилятор так преобразует ? Может я что-то завышаю, но я на 90 процентов уверен, что если спросить 100 среднестатистических программистов почему int a[x]~*((element_type_x*)&a+x), то ответит максимум 5.
K&R ещё не до конца изучил, неужели дальше это будет ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556515
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
под тильдой я имел ввиду эквивалентность как математический символ, а не оператор C
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556533
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryя на 90 процентов уверен, что если спросить 100 среднестатистических
программистов почему int a[x]~*((element_type_x*)&a+x), то ответит максимум 5.
Обычно начинающих сильнее ставит в тупик вопрос "почему (int*)0 + 1 == 4".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556555
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня следующее предположение, 0 приводится к указателю, и при добавлении единички работает арифметика указателей, то есть добавляют 4 байта на int, и возвращается 4.Возникает два вопроса
1)Почему (int*)a=a (где а in Z, не переменная)
2)почему возможен возврат числа не кратному 4, но видимо ответ из 1 вопроса

Если мне есть ещё смысл думать, то я подумаю, если я вообще не в ту степь смотрю, то вы лучше подскажите
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556556
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
f e:
printf("%i",(int*)17+10 );

вернёт 57
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556577
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryУ меня следующее предположение, 0 приводится к указателю, и при добавлении единички работает арифметика указателей, то есть добавляют 4 байта на int, и возвращается 4.Возникает два вопроса
1)Почему (int*)a=a (где а in Z, не переменная)
не понял о чем речь
SashaMercury2)почему возможен возврат числа не кратному 4, но видимо ответ из 1 вопроса
если ты про это
SashaMercuryf e:
printf("%i",(int*)17+10 );

вернёт 57
то все верно:
(int*)17 - указатель на байт памяти с адресом 17. Нет никаких ограничений чтобы начальный адрес был кратен 4. Память адресуется побайтно.
+10 как ты уже понял 10 раз по 4 байта (sizeof(int)).

SashaMercuryЕсли мне есть ещё смысл думать, то я подумаю, если я вообще не в ту степь смотрю, то вы лучше подскажите
Наверно есть смысл прекращать теорию изучать и написать что-нибудь простое, для закрепления теории на практике.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556583
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SS

Дайте какое-нибудь задание C:
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556585
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSПочему (int*)a=a (где а in Z, не переменная


a in Z, это как в Tex, число "а" принадлежит целым числам, но не переменная, то есть не объявлена как int a;
f e: (int*)100. 100-это и есть a


Dima_TНаверно есть смысл прекращать теорию изучать и написать что-нибудь простое, для закрепления теории на практике.

Дайте какое-нибудь задание C:
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556622
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercurySSПочему (int*)a=a (где а in Z, не переменная

a in Z, это как в Tex, число "а" принадлежит целым числам, но не переменная, то есть не объявлена как int a;
f e: (int*)100. 100-это и есть a
Код: plaintext
1.
(int*)100 = ...


В реальном коде такого не надо писать. Это запись в ячейки памяти с адресами 100, 101, 102, 103.
Уже как-то писал что в реальном коде такое невозможно, т.к. конкретные адреса в памяти выделяются ОС и программа работает с теми адресами что ей дали, поэтому конкретное значение указателя нужно только для сравнения его с другим указателем на тот же массив.
SashaMercuryДайте какое-нибудь задание C:
В книжках ничего нет?

Напиши что-нибудь классическое с использованием указателей. Например сортировка массива и двоичный поиск по нему
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38556710
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЯ его полностью понял
SashaMercuryСегодня с трудом заснул, думал про эту формулу

Предлагаю для проверки понимания перед сном подумать над тем как будет вычислено выражение:
Код: plaintext
1.
3["abcdef"]
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38557182
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вышел из дома, компилятора тут нет, только C# к сожалению. Попробую предположить.

3["abcdef"]. Видим операцию [], значит получим *(3+"abcdef")..мне кажется что abcdef запишется в памяти в соответствии с ASCII, и будет прочитано число как int.Хотя стоп, это 6 байт,а int 4 байта.Нет. Вероятнее добавится 6 байт, даже 7, ещё конец массива. На выходе будет 10. Верно ?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38557285
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЯ вышел из дома, компилятора тут нет, только C# к сожалению. Попробую предположить.

3["abcdef"]. Видим операцию [], значит получим *(3+"abcdef")..мне кажется что abcdef запишется в памяти в соответствии с ASCII, и будет прочитано число как int.Хотя стоп, это 6 байт,а int 4 байта.Нет. Вероятнее добавится 6 байт, даже 7, ещё конец массива. На выходе будет 10. Верно ?

Нет.

Подумай, какого типа и значения выражение

Код: plaintext
1.
"abcdef"
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38557959
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,спасибо..
3+97 значит.Адрес сдвинется на 97. Вернёт 100.Проверил уже.
Что-же я сразу не догадался что будет сдвиг на значение указателя на начало строки (
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38558157
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury3+97 значит.Адрес сдвинется на 97. Вернёт 100.Проверил уже.
Неа, это еще бредовее предыдущей попытки угадать :)

Подсказка:
Строковый литерал в С - это массив char.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38558159
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryВернёт 100.Проверил уже
Вопрос был не что вернет, а как вычисляется :)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559352
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так ?

3["abcdef"]=3[array]=*(3+array)=*(3+(int*)array)=*(3+(int*)(&array[0]))=100
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559545
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

здесь тебе только стандарт поможет

во-первых, тебе потребуется определение []

Код: plaintext
1.
a[b] = *(a+b) = *(b+a) = b[a]



во-вторых, правила адресной арифметики

Код: plaintext
1.
2.
3.
4.
T* add(T* p, size_t offset) {

   return (T*)((void*)p+offset*sizeof(T));
}


итого

Код: plaintext
1.
3["abcdef"] = *(3+"abcdef") = *("abcdef" + 3)  = "abcdef"[3] = 'd' 



откуда 100?
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559595
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широковоткуда 100?
ASCII код 'd' = 100
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559609
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

да, ступил :) просто смутили манипуляции товарища с (int*) где его в принципе нет :)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559979
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, я немного понял.

Анатолий Широков 3["abcdef"] = *(3+"abcdef") = *("abcdef" + 3) = "abcdef"[3] = 'd'


Распишите более подробно пожалуйста, где происходит приведение к int*


Анатолий Широковa[b] = *(a+b) = *(b+a) = b[a]


Возможна такая ситуация что смысл будет иметь и *(a+b) и *(b+a). Я не придумал, но возможно 3[5], вернёт видимо 3+20 либо 3+12.
Не могу проверить и оценить, буквально с закрытыми глазами уже печатаю.
Это очень интересно. Мне нравится что это напоминает норму элемента в пространстве в функане. Интересно, а где дано математическое обоснование указателей ?
И откуда вы всё это узнали ?Это есть в K&R ?

Сегодня спросил у знакомого, он хвастался что прилично соображает в Си, он сказал что будет ошибка компиляции, но я то знал что будет =^_^=
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38559997
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо C:
Пример жутко хороший )))
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560003
SS_phone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оно нигде не происходит, это я вывожу в таком формате
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560020
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЯ не придумал, но возможно 3[5], вернёт видимо 3+20 либо 3+12
Все еще нет понимания.
Разбирайтесь заново :)
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560037
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСпасибо, я немного понял.

Распишите более подробно пожалуйста, где происходит приведение к int*


нет здесь вообще приведения к int* нигде.

SashaMercury
Возможна такая ситуация что смысл будет иметь и *(a+b) и *(b+a). Я не придумал, но возможно 3[5], вернёт видимо 3+20 либо 3+12.


не возможна, а узнают это в первоисточнике - стандарте С/С++
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560380
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskySashaMercuryЯ не придумал, но возможно
Код: plaintext
1.
3[5]

, вернёт видимо 3+20 либо 3+12
Все еще нет понимания.
Разбирайтесь заново :)

Саша, всё настолько просто, что ...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
ziv@mole:~/tmp$ cat a.c
 [code=plaintext]
#include <stdio.h>

int main()
{
  void *a = (void*) (3);
  printf( "%u: 3[5] = %u, 5[3] = %u \n", sizeof(a[0]), (unsigned)(&a[5]), (unsigned)(&5[a]) );

  char *a1 = (char*) (3);
  printf( "%u: 3[5] = %u, 5[3] = %u \n", sizeof(a1[0]), (unsigned)(&a1[5]), (unsigned)(&5[a1]) );

  short *a2 = (short*) (3);
  printf( "%u: 3[5] = %u, 5[3] = %u \n", sizeof(a2[0]), (unsigned)(&a2[5]), (unsigned)(&5[a2]) );

  int *a3 = (int*) (3);
  printf( "%u: 3[5] = %u, 5[3] = %u \n", sizeof(a3[0]), (unsigned)(&a3[5]), (unsigned)(&5[a3]) );

  double *a4 = (double*) (3);
  printf( "%u: 3[5] = %u, 5[3] = %u \n", sizeof(a4[0]), (unsigned)(&a4[5]), (unsigned)(&5[a4]) );

  return 0;
}


ziv@mole:~/tmp$ gcc -w -oa a.c && ./a
1: 3[5] = 8, 5[3] = 8
1: 3[5] = 8, 5[3] = 8
2: 3[5] = 13, 5[3] = 13
4: 3[5] = 23, 5[3] = 23
8: 3[5] = 43, 5[3] = 43
ziv@mole:~/tmp$


...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560554
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я понял.. перед сном и написал что приведение не происходит. в формате i вывожу, потому 100

SS_phoneОно нигде не происходит, это я вывожу в таком формате


Я хотел скачать стандарт С/С++ , но он платный. Подскажите ссылку, пожалуйста
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560566
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Экспериментировал. например 3[&"abcdef"] вернёт адрес третьего элемента массива char, то есть адрес d.
&abc[2] так значит тоже можно писать.

3[&"abcdef"]=*(3+&"abcdef")=*(&"abcdef"+3)=&"abcdef"[3]=Дальше по идее должно быть =&*("abcdef"+3). но что-то мне не нравится.
Сначала прочитаю стандарт потом буду размышлять.
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38560766
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЭкспериментировал. например 3[&"abcdef"] вернёт адрес третьего элемента массива char, то есть адрес d.
&abc[2] так значит тоже можно писать.

Тут только не надо забывать что
Код: plaintext
1.
&abc[2]


означает
Код: plaintext
1.
&(abc[2])


а не
Код: plaintext
1.
(&abc)[2]



SashaMercuryЯ хотел скачать стандарт С/С++ , но он платный. Подскажите ссылку, пожалуйста
Сами стандарты платные, но доступны последние черновики стандартов, которые ничем кроме названия и некоторых мелочей не отличаются. Ну и иногда в инете валяются и собственно стандарты :)
Ниже привожу ссылки либо на черновик (на сайте стандартов open-std) либо на стандарт (на других сайтах) .

С99: http://cs.nyu.edu/courses/fall12/CSCI-GA.2110-001/downloads/C99.pdf
C11: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
С++03: http://cs.nyu.edu/courses/fall11/CSCI-GA.2110-003/documents/c 2003std.pdf
С++11: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3242.pdf
С++14 (еще не принят): http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3797.pdf
...
Рейтинг: 0 / 0
K&R Многомерные массивы
    #38562577
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, здравствуйте.

Черновики стандартов сейчас скачал, спасибо)
...
Рейтинг: 0 / 0
66 сообщений из 66, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / K&R Многомерные массивы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]