{int i;
for(i=0;i<m-1;i++)
n*=n;
return n;
}
/*часткове транспонування n-вимірної матриці*/
int* ctranspon (int *a,int n,int m)
{
int *rob1,*rob=(int*)malloc(sizeof(int)*pow(n,m));
rob1=rob;
long i,j;
int *s;
for (j=0;j<n;j++)
{
s=a++;
for(i=0; i<pow(n,m-1); i++)
*rob++=*(s+i*n);
}
return rob1;
}
При реалізації безпосередньо множення матриць записуватиме результат множення окремих компонент у деякий масив. Причому на вхід функції передаватимуться блоки, що множаться, розмірності та адреса, куди записувати відповідні результати множення (у нашому випадку це **c). Після запису інформації за кожного виклику функції відповідна адреса має змінюватись (зсуватись на кількість елементів, що вже записані). Однак у С при передаванні адреси створюється її локальна копія у функції. Якщо передати у функцію просто адресу, то ми не зможемо з функції її змінити. Отже, необхідно передавати адресу цієї адреси (або використовувати механізм посилань, реалізований у С++). Виникає також проблема коректного виділення пам'яті для результату множення. Запишемо функцію:
void dobutok(int* a, int* b, int** c, int n, int m)
|
|
/*змінна c буде містити результат множення і, оскільки функція рекурсивно буде змінювати сам покажчик, то будемо передавати у функцію його адресу*/
{
int *arob=(int*)malloc(sizeof(int)*pow(n,m-1));
int *brob=(int*)malloc(sizeof(int)*pow(n,m-1));
if(m==2)
{
//добуток двовимірних матриць
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
*(*c+i*n+j)=0;
for(int k=0;k<n;k++)
*(*c+i*n+j)+=*(a+i*n+k)**(b+k*n+j);
}
(*c)+=n*n;
}
Else
{
b=ctranspon(b,n,m);
//формування блоків
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
arob=a+i*pow(n,m-1);
brob=b+j*pow(n,m-1);
dobutok(arob,brob,c,n,m-1);
}
}
}
Main()
{
int n,m,i,size;
printf("введіть розмірність матриць та вимірність(>=2)\n')
scanf("%d%d',&n,&m);
size=pow(n,m);
int a=(int*)malloc(sizeof(int)*size);
int *b=(int*)malloc(sizeof(int)*size);
int sizerezult; /*кількість елементів результуючої матриці. Вона залежить від розмірності. Добуток двовимірних матриць - двовимірна, тривимірних - чотиривимірна, для всіх інших розмірність збільшується на два. Відповідно кількість елементів визначається як розмірність у степені вимірності*/
Swich(m)
{
case 2: sizerezult=size; break;
case 3:sizerezult=size*n; break;
default: sizerezult=size*n*n;
}
int *cp,*c=(int*)malloc(sizeof(int)*sizerezult);
cp=c;
printf("введіть матриці \n')
printf("матриця А:\n');
for(i=0;i<size;i++) scanf("%d',a+i);
printf("матриця B:\n');
for(i=0;i<size;i++) scanf("%d',b+i);
dobutok(a,b,&c,2,3);
clrscr();
for(int i=0;i<sizerezult;i++)
printf("%d",*(cp+i));
}
9. Програма, що друкує сама себе.Напишемо програму, яка друкує сама себе. Такі програми дуже популярні серед студентів, що починають вивчати різні мови програмування. При цьому одразу ж необхідно уточнити, що текст програми має зберігатись у самій програмі. Застосування будь-яких зовнішніх джерел заборонено. Використовуватимемо масив покажчиків на рядки:
#include <stdio.h>/*1*/char *s[]=/*2*/{/*3*/"#include <stdio.h>' "char *s[]=","{","рядок 4",...,"рядок N"}; /*4*/рядок програми 5/*5*/... /*6*/рядок програми N/*7*/ Роздрукувати програму можна, використовуючи цикл for . Загальна технологія: спочатку друкуємо перші три рядки програми як s[0],s[1],s[2]: for(i=0; i<2; i++) {fputs(s[i], stdout); putc(NEW_LINE,stdout);}Отримаємо:
|
|
потім – усі елементи, що ініціалізують масив покажчиків s . При цьому необхідно друкувати відкриваючі лапки, s[i] , закриваючі лапки, кому (крім останнього рядка) і новий рядок. У рядкових константах не можна використовувати лапки й символ нового рядка, тому доведеться використовувати їх коди – відповідно 34 та 10 (для ASCII).
for(j=0; j<21; j++){putc(QUOTE,stdout);fputs(s[j], stdout);putc(QUOTE,stdout);putc(',',stdout);putc('\n',stdout);getch();}Отримаємо всі рядки, що ініціалізують масив s:
"#include <stdio.h>' "char *line[]=","{","рядок 4",...,"рядок N"Далі друкуємо елементи масиву s, починаючи з четвертого (у схемі – "рядок 4"):
for(; i<21; i++){fputs(s[i],stdout);putc(NEW_LINE,stdout);}Отримаємо:};/*4*/рядок 4/*5*/... /*6*/рядок N/*7*/ У наведеній схемі не використовуються пропуски, що не принципово.Рядок N має містити закриваючу фігурну дужку, а набір рядків – функцію main() і відкриваючу фігурну дужку. Усе інше в переліку рядків може бути довільним. Текст програми: #include <stdio.h>char *s[]={"#include <stdio.h>","char *s[]={","};","#define QUOTE 34","#define NEW_LINE 10","int main()","{","int i,j;","for(i=0; i<2; i++)","{fputs(s[i], stdout);","putc(NEW_LINE,stdout);}","for(j=0; j<21; j++)","{putc(QUOTE);","fputs(s[j], stdout);","putc(QUOTE,stdout);","putc(',',stdout);","putc(NEW_LINE,stdout);}","for(; i<21; i++)","puts(line[i], stdout);","return 0;","}",};#define QUOTE 34 #define NEW_LINE 10int main(){int i,j;for(i=0; i<2; i++){fputs(s[i], stdout);putc(NEW_LINE,stdout);}for(j=0; j<21; j++){putc(QUOTE,stdout);fputs(s[j],stdout);putc(QUOTE,stdout);putc(',',stdout);putc('\n',stdout);getch();}for(; i<21; i++){fputs(s[i],stdout);putc(NEW_LINE,stdout);}return 0;}