<!DOCTYPE html>
<html>
<body>
<p id="p1">
<b>Enter the no of row and column to create table:</b>
<br/><br/>
<table>
<tr>
<th>No. of Row(s) </th>
<th>No. of Column(s)</th>
</tr>
<tr>
<td><input type="text" id="row" value="4" /> X</td>
<td><input type="text" id="col" value="7" />Y</td>
</tr>
</table>
<br/>
<button id="create" onclick="create()">create table</button>
</p>
<br/><br/>
<input type="button" value="Reload page" onclick="reloadPage()">
<script>
function create() {
var row = parseInt(document.getElementById("row").value);
var col = parseInt(document.getElementById("col").value);
var tablestart="<table id=myTable border=1>";
var tableend = "</table>";
var trstart = "<tr bgcolor=#ff9966>";
var trend = "</tr>";
var tdstart = "<td>";
var tdend = "</td>";
var data="data in cell";
var str1=tablestart + trstart + tdstart + data + tdend + trend + tableend;
document.write(tablestart);
for (var r=0;r<row;r++) {
document.write(trstart);
for(var c=0; c<col; c++) {
document.write(tdstart+"Row."+r+" Col."+c+tdend);
}
}
document.write(tableend);
document.write("<br/>");
var s="<button id="+"delete"+" onclick="+"deleteTable()"+">Delete top Row </button>";
document.write(s);
var relod="<button id="+"relod"+" onclick="+"reloadPage()"+">Reload Page </button>";
document.write(relod);
}
function deleteTable() {
var dr=0;
if(confirm("It will be deleted..!!")) {
document.getElementById("myTable").deleteRow(dr);
}
}
function reloadPage(){
location.reload();
}
</script>
</body>
</html>
Да, вы можете это сделать, и нет, вам не нужен другой массив указателей, как вам говорят большинство других ответов. Вам нужен вызов:
int (*MAGICVAR)[200] = malloc(400 * sizeof *MAGICVAR);
MAGICVAR[20][10] = 3; // sets the (200*20 + 10)th element
Если вы хотите объявить функцию, возвращающую такой указатель, вы можете сделать это следующим образом:
int (*func(void))[200]
{
int (*MAGICVAR)[200] = malloc(400 * sizeof *MAGICVAR);
MAGICVAR[20][10] = 3;
return MAGICVAR;
}
Или использовать typedef, что делает его немного понятнее:
typedef int (*arrayptr)[200];
arrayptr function(void)
{
/* ... */
Если дополнительное косвенное обращение не вызывает беспокойства, вы можете использовать массив указателей.
Править
Вот вариант ответа @Platinum Azure, который не делает так много вызовов malloc. Помимо более быстрого распределения, все элементы гарантированно будут смежными:
#define ROWS 400
#define COLS 200
int **memory = malloc(ROWS * sizeof(*memory));
int *arr = malloc(ROWS * COLS * sizeof(int));
int i;
for (i = 0; i < ROWS; ++i)
{
memory[i] = &arr[i * COLS];
}
memory[20][10] = 3;
В том же духе, что и ответ Cogwheel, вот (несколько грязный) трюк, который делает только один вызов malloc ()
:
#define ROWS 400
#define COLS 200
int** array = malloc(ROWS * sizeof(int*) + ROWS * COLS * sizeof(int));
int i;
for (i = 0; i < ROWS; ++i)
array[i] = (int*)(array + ROWS) + (i * COLS);
Это заполняет первую часть буфера указателями на каждую строку в следующем, непрерывном массиве данных.
Компилятор и среда выполнения не имеют возможности узнать ваши предполагаемые размерности, используя только умножение в вызове malloc.
Вам нужно использовать двойной указатель, чтобы достичь возможности двух индексов. Что-то вроде этого должно получиться:
#define ROWS 400
#define COLS 200
int **memory = malloc(ROWS * sizeof(*memory));
int i;
for (i = 0; i < ROWS; ++i)
{
memory[i] = malloc(COLS * sizeof(*memory[i]);
}
memory[20][10] = 3;
Убедитесь, что вы проверили все возвращаемые значения malloc на наличие возвратов NULL, указывающих на ошибку выделения памяти.
int** memory = malloc(sizeof(*memory)*400);
for (int i=0 ; i < 400 ; i++)
{
memory[i] = malloc(sizeof(int)*200);
}
Используйте указатель на массивы:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int (*arr)[10];
arr = malloc(10*10*sizeof(int));
for (int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
arr[i][j] = i*j;
for (int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
printf("%d\n", arr[i][j]);
free(arr);
return 0;
}
#define ROWS 400
#define index_array_2d(a,i,j) (a)[(i)*ROWS + (j)]
...
index_array_2d( memory, 20, 10 ) = -1;
int x = index_array_2d( memory, 20, 10 );
Массивы и указатели выглядят почти одинаково, но компилятор обрабатывает их по-разному.Давайте посмотрим, что нужно сделать для индексации массива и отмены ссылки на указатель со смещением:
Допустим, мы объявили статический массив (массив в стеке немного сложнее, фиксированное смещение от регистра, но, по сути, то же самое):
статический массив int [10];
И указатель:
статический int * указатель;
Затем мы отменяем уважение для каждого следующим образом:
x = array [i];
x = pointer [i];
Следует отметить, что адрес начала массива
, а также адрес указателя
(не его содержимое) фиксированы во время ссылки / загрузки. Затем компилятор выполняет следующие действия:
массива
отмена ссылки:
i
, array
, то есть к его фиксированному адресу, чтобы сформировать целевой адрес памяти, указатель
отмены ссылки:
i
, указателя
, то есть содержимое по его адресу, То же самое происходит с 2D-массивом с дополнительными шагами по загрузке второго индекса и его умножению на размер строки (который является константой). Все это решается во время компиляции, и во время выполнения нет возможности заменить одно другим.
@caf здесь имеет правильное решение. В конце концов, в языке есть законный способ индексировать указатель как двумерный массив.