Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перевод на Си / 25 сообщений из 46, страница 1 из 2
08.09.2021, 15:47
    #40096027
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Как можно написать в Си?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
for(j = 0; j <= 1; j++)
{
    R[j][0] = rp = 0;
    i = 1;
    while(i <= strlen(buf))
    {
        while(buf[i - rp - 1] == buf[i + j + rp])
            rp++;
        R[j][i] = rp;
        k = 1;
        while((R[j][i - k] != rp - k) && (k < rp))
        {
            R[j][i + k] = min(R[j][i - k],rp - k);
            k++;
        }
        rp = max(rp - k,0);
        i += k;
    }
}
...
Рейтинг: 0 / 0
08.09.2021, 15:48
    #40096028
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Вообще-то это уже на Си...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
08.09.2021, 15:51
    #40096030
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
R[j,0] - на 0 выражение должно иметь тип указателя на объект, но имеет тип "int"
...
Рейтинг: 0 / 0
08.09.2021, 15:53
    #40096032
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Код: sql
1.
R[j][0]


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
08.09.2021, 15:56
    #40096036
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Dimitry Sibiryakov,ой, пардон, да R[j][0] = rp = 0; - вот здесь
...
Рейтинг: 0 / 0
08.09.2021, 15:58
    #40096038
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
ругается, что индексируемое значение не является ни массивом, ни указателем, ни вектором
...
Рейтинг: 0 / 0
08.09.2021, 16:04
    #40096040
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
kasper_,

Покажи, как объявлено R.
...
Рейтинг: 0 / 0
08.09.2021, 16:09
    #40096042
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
AmKad,
Код: c
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        int i, j, k,   // iterators
        rp;        // length of radius

        int *R;  // указатель на массив
        int n, m;
        n = 2;
        m = strlen(buf) + 1;
        // Выделение памяти
        R = (int*)malloc(n*m * sizeof(int));
        // Ввод элементов массива
        for (i = 0; i        {
            for (j = 0; j            {
                printf("R[%d][%d] = ", i, j);
                scanf("%d", (R + i*m + j));
            }
        }
...
Рейтинг: 0 / 0
08.09.2021, 16:11
    #40096044
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
в с++ бы было
Код: plaintext
1.
2.
    const int N = 20; //например
    int R[2][N+1];
...
Рейтинг: 0 / 0
08.09.2021, 16:20
    #40096047
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Чтобы работать с двумерным массивом, надо знать размер "строки" массива.
Если ты объявляешь int *R - то компилятор не знает насколько длинная строка в массиве и ругается.
Так что тебе придется эмулировать двумерный массив вручную.

Код: plaintext
1.
2.
3.
4.
int *R = malloc( number_of_rows * row_size * sizeof(int));
R[ y*row_size + x ] = ...;
/// это полностью эквивалентно
* (R + y*row_size + x )  = ...;
...
Рейтинг: 0 / 0
08.09.2021, 16:39
    #40096059
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
На, поиграйся:
Код: 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.
#include <stdio.h>

#define N 2
#define M 3
int main(int argc, char **argv) {
	int arr[N][M];

	printf("sizeof(arr) = %ld\n", sizeof(arr));
	printf("sizeof(arr[0]) = %ld\n\n", sizeof(arr[0]));

	for (int i=0; i<N*M; i++) {
		printf("%p = %d\n", ((int*)arr)+i, i);
		*(((int*)arr)+i) = i;
	}
	printf("\n");

	for(int n=0; n<N; n++) {
		for(int m=0; m<M; m++) {
			printf("%p ", &arr[n][m]);
		}
		printf("\n");
	}
	printf("\n");

	for(int n=0; n<N; n++) {
		for(int m=0; m<M; m++) {
			printf("%d ", arr[n][m]);
		}
		printf("\n");
	}

	return 0;
}
...
Рейтинг: 0 / 0
08.09.2021, 16:59
    #40096071
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
kasper_,

компилируешь С-код компилятором С++, он жестче проверяет типы.

или компилируй как С или обнули указатель отдельно NULL

Кстати, неверно объявлен R, должно быть int **R;
...
Рейтинг: 0 / 0
08.09.2021, 17:15
    #40096081
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Siemargl
компилируешь С-код компилятором С++, он жестче проверяет типы.
Нет. Не жестче, а по другому.

Siemargl
или компилируй как С или обнули указатель отдельно NULL
Это зачем?

Siemargl
Кстати, неверно объявлен R, должно быть int **R;
Совсем не верный совет.
...
Рейтинг: 0 / 0
08.09.2021, 19:15
    #40096120
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Спасибо, буду разбираться
...
Рейтинг: 0 / 0
08.09.2021, 20:16
    #40096144
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Что-то туплю. Сначала

1. У меня есть в буфере некая строка, её длину можно определить, как strlen(buf)
2. Мне нужно создать таблицу из двух строк, которая на С++ бы выглядела, как int R[2][strlen(buf)+1]
3. Пытаюсь реализовать это следующим образом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        int i, j, n, m;
        n = 2;
        m = strlen(buf) + 1;
        // Выделение памяти
        //R = (int*)malloc(n*m * sizeof(int));
        int **R = (int*)malloc(n*m * sizeof(int));
        // Ввод элементов массива
        for (i = 0; i<n; i++)
        {
            for (j = 0; j<m; j++)
            {
                printf("R[%d][%d] = ", i, j);
                scanf("%d", (R + i*m + j));
            }
        }



что-то не так?
...
Рейтинг: 0 / 0
08.09.2021, 20:41
    #40096152
kasper_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Код: plaintext
1.
2.
3.
4.
int **R = (int **)malloc(n*sizeof(int *));
for(int i = 0; i < n; i++) {
    R[i] = (int *)malloc(m*sizeof(int));
}
...
Рейтинг: 0 / 0
09.09.2021, 01:25
    #40096182
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
White Owl
Siemargl
компилируешь С-код компилятором С++, он жестче проверяет типы.
Нет. Не жестче, а по другому.

Siemargl
или компилируй как С или обнули указатель отдельно NULL
Это зачем?

потому что у топика R[j][0] = rp = 0;
в общем проблема из-за неверного типа R, но мой совет ниже неверен и обойти через int**R не получится (размер *R неизвестен и индексация будет неверной)

White Owl

Siemargl
Кстати, неверно объявлен R, должно быть int **R;
Совсем не верный совет.

это да, я неправ, тут в С дырка - массив массивов немного не то, что массив указателей, хотя синтаксис один.
собственно, прямого решения нет, только через пересчет индексов
kasper_
Код: plaintext
1.
2.
3.
4.
int **R = (int **)malloc(n*sizeof(int *));
for(int i = 0; i < n; i++) {
    R[i] = (int *)malloc(m*sizeof(int));
}

Похоже на правду
...
Рейтинг: 0 / 0
09.09.2021, 04:42
    #40096187
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
kasper_
что-то не так?
Двойной указатель "не так".
**R не является R[][] даже близко.
...
Рейтинг: 0 / 0
09.09.2021, 04:48
    #40096188
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
kasper_
1. У меня есть в буфере некая строка, её длину можно определить, как strlen(buf)
2. Мне нужно создать таблицу из двух строк, которая на С++ бы выглядела, как int R[2][strlen(buf)+1]
Это очень не хороший и опасный подход. strlen() тебе выдаст фактическую длину строки, да. Но это одна строка, что если у тебя вторая строка будет длиннее первой? Лучше заранее ограничь длину строки, просто задай что "на вход мы получаем не больше стольки-то символов".
И будет у тебя int R[2][sizeof(buf)] а все строки не больше чем sizeof(buf)-1 и гарантия что (в данном месте) ты не порушишь память получив GPF.
...
Рейтинг: 0 / 0
09.09.2021, 05:00
    #40096190
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
kasper_
Код: plaintext
1.
2.
3.
4.
int **R = (int **)malloc(n*sizeof(int *));
for(int i = 0; i < n; i++) {
    R[i] = (int *)malloc(m*sizeof(int));
}

Да, так можно. Но это уже другая структура данных.
Это массив указателей на массивы. Тут каждая строка "двумерного" массива может находится в любом месте памяти и для перехода с одной строки на другую надо обязательно обращаться к базовому массиву указателей.
Так удобно делать если "строки" этого двумерного массива могут быть разной длины (естественно надо будет как-нибудь еще помнить длину "строк"), но для реальных ASCIIz строк такое действительно часто используется.


Для целых и математики, все-же удобнее использовать массив массивов (int R[N][M] или int *R = malloc(N*M)) тогда "строки" двумерного массива строго одинаковой длины, все строки располагаются в памяти строго друг за другом и переход с одной строки на другую очень легко обрабатывается кешем процессора и намного быстрее работает.
...
Рейтинг: 0 / 0
09.09.2021, 14:00
    #40096331
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
White Owl
На, поиграйся:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <stdio.h>

#define N 2
#define M 3
int main(int argc, char **argv) {
	int arr[N][M];

	printf("sizeof(arr) = %ld\n", sizeof(arr));
	printf("sizeof(arr[0]) = %ld\n\n", sizeof(arr[0]));

	for (int i=0; i<N*M; i++) {
		printf("%p = %d\n", ((int*)arr)+i, i);
		*(((int*)arr)+i) = i;
	}
        // ...
}

UB.
...
Рейтинг: 0 / 0
09.09.2021, 15:12
    #40096363
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
a guest
White Owl
На, поиграйся:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <stdio.h>

#define N 2
#define M 3
int main(int argc, char **argv) {
	int arr[N][M];

	printf("sizeof(arr) = %ld\n", sizeof(arr));
	printf("sizeof(arr[0]) = %ld\n\n", sizeof(arr[0]));

	for (int i=0; i<N*M; i++) {
		printf("%p = %d\n", ((int*)arr)+i, i);
		*(((int*)arr)+i) = i;
	}
        // ...
}

UB.
С чего это вдруг UB? Это как раз стандартная адресная арифметика.
...
Рейтинг: 0 / 0
09.09.2021, 15:26
    #40096374
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
White Owl
a guest
пропущено...
UB.
С чего это вдруг UB? Это как раз стандартная адресная арифметика.
«Стандартная адресная арифметика» это когда имея указатель на arr[0][0] (ведь ожидается что (int*)arr выдаст именно его?), итерируешь от 0 до M. А тут итерируется до N*M, что > M.
Ну и вообще я не знаю в стандарте C гарантий того, что (int*)arr это указатель на arr[0][0] (а в C++ явно гарантируется что это не так).
...
Рейтинг: 0 / 0
09.09.2021, 15:38
    #40096382
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
Если посмотреть на строку в другом контексте
Код: plaintext
1.
2.
3.
int arr[N];
...
*(((int*)arr)+i) = i;


то это будет равносильно
Код: plaintext
1.
arr[i] = i;


никакого UB тут нет и быть не может.
...
Рейтинг: 0 / 0
09.09.2021, 15:45
    #40096386
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перевод на Си
a guestв C++ *явно* гарантируется что это не так

В С++ явно гарантируется, что переменная типа "массив" неявно приводится к
указателю на подлежащий тип, имеющий значение адреса первого (то бишь нулевого)
элемента массива. От количества проделанных этих преобразований результат не
меняется.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перевод на Си / 25 сообщений из 46, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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