用C语言编写一个矩阵转置的函数,矩阵的行数和列数在程序中由用户输入,请问怎么写,非常感谢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言编写一个矩阵转置的函数,矩阵的行数和列数在程序中由用户输入,请问怎么写,非常感谢相关的知识,希望对你有一定的参考价值。

我的代码逻辑是:

矩阵行指针初值指向每行首地址,迭代依次取所有行指针指向值组成新行,所有行指针自增。最终组合新的矩阵。

#include <stdio.h>
#include <malloc.h>
int **getList(int row,int clo);//获取矩阵地址空间
void setNum(int **nList,int n);//填写数值
void prtList(int **nList,int row,int clo);//打印矩阵
int **zz(int **nList,int row,int clo);//转置函数

int main()

    int row,clo,**nList=NULL,**nListSave=NULL;

    printf("输入矩阵行列数:");
    scanf("%d%d",&row,&clo);
    nList=getList(row,clo);
    setNum(nList,row*clo);

    printf("输入的矩阵为:\\n");
    prtList(nList,row,clo);

    printf("转置后的矩阵为:\\n");
    nListSave=zz(nList,row,clo);
    free(nList);
    nList=nListSave;
    prtList(nList,clo,row);
    return 0;


int **zz(int **nList,int row,int clo)

    int *nSave=NULL,**listSave=NULL,**listp=nList,*p=NULL,i,j;
    nSave=(int *)malloc(sizeof(int)*row*clo);
    listSave=(int **)malloc(sizeof(int*)*clo);//倒置后的矩阵
    p=nSave;

    for(j=0;j<clo;j++)
    
        for(i=0;i<row;i++)
        
            *p++=*listp[i];
            listp[i]=listp[i]+1;
        
    
    for(i=0;i<clo;i++)
        listSave[i]=&nSave[i*row];

    for(i=0;i<row;i++)
        free(nList[i]);//释放原矩阵行空间
    return  listSave;

void prtList(int **nList,int row,int clo)

    int i,j;
    for(i=0;i<row;i++)
    
        for(j=0;j<clo;j++)
            printf("%d ",nList[i][j]);
        printf("\\n");
    

void setNum(int **nList,int n)

    int *p=nList[0];
    printf("填写矩阵中%d个数值:\\n",n);
    while(n-->0)
        scanf("%d",p++);

int **getList(int row,int clo)

    int *nums,**nList,i;
    nums=(int *)malloc(sizeof(int)*row*clo);
    nList=(int **)malloc(sizeof(int*)*row);
    for(i=0;i<row;i++)
        nList[i]=&nums[i*clo];
    return nList;

参考技术A

这是我以前写的,你修改一下#define N 4这个语句就可以用了

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 4
void main()

int i,j;
int a[3*N],b[N][3];//这里我设置旋转为4*4的矩形,自己在这里改成其它的矩形
int *p=a;//用指针来指向这个一维数组。这样在旋转赋值的时候会轻松很多
srand(time(NULL));
for(i=0;i<N*3;i++)

a[i]=rand()%100;//随机生成0~99
printf("%d\\t",a[i]);
if((i+1)%4==0)
printf("\\n");


for(i=N-2;i>=0;i--) //旋转
for(j=0;j<N;j++,p++)
b[j][i]=*p;



printf("顺时针旋转90度后:\\n");
for(i=0;i<N;i++) //
for(j=0;j<N-1;j++)
printf("%d\\t",b[i][j]);
printf("\\n");



趣味C语言

一、矩阵转置

分析:
(1)先分别输入数组的行数和列数;
(2)逐个输入数组中的元素,元素个数为刚刚输入的行数与列数的乘积;
(3)通过for循环进行转置;
(4)最终将统计出的结果输出到屏幕上;
代码实现:

#include <stdio.h>
int main()

	int i, j, row, column;                           //定义表示数组行列的变量
	int a[10][10], b[10][10];                     //定义二维数组
	printf("Please input the number of rows (<10)\\n");
	scanf("%d", &row);                             //输入行数
	printf("please input the number of columns(<10)\\n");
	scanf("%d", &column);                          //输入列数
	printf("Please input the elements of the array\\n");
	for (i = 0; i < row; i++)                            //控制输出的行数
	
		for (j = 0; j < column; j++)                     //控制输出的列数
		
			scanf("%d", &a[i][j]);                 //输入数组中的元素
		
	
	//矩阵转置之前
	printf("array a:\\n");                          //将输入的数据以二维数组的形式输出
	for (i = 0; i < row; i++)                             //控制输出的行数
	
		for (j = 0; j < column; j++)                     //控制输出的列数
		
			printf("\\t%d", a[i][j]);               //输出元素
		
		printf("\\n");                               //每输出一行要在末尾换行
	

	//矩阵转置过程
	for (i = 0; i < row; i++)
	
		for (j = 0; j < column; j++)
		
			b[j][i] = a[i][j];              //将a数组的i行j列元素赋给b数组的j行i列元素
		
	
	//矩阵转置之后
	printf("array b:\\n");                           //将互换后的b数组输出
	for (i = 0; i < column; i++)                           //b数组行数最大值为a数组列数
	
		for (j = 0; j < row; j++)                           //b数组列数最大值为a数组行数
		
			printf("\\t%d", b[i][j]);                 //输出b数组元素
		
		printf("\\n");                                 //每输出一行要在末尾换行
	
	return 0;

运行截图:

二、猜宝游戏

描述:初始时,甲的左手握着一枚硬币,游戏开始后,甲进行有限次或真或假的交换,最后由乙来猜测这两只手中是否有硬币。
分析:
(1)使用基类型的变量作为形参,构造交换函数;
(2)使用指针变量作为形参,在函数体中交换指针的指向;
(3)使用指针变量作为形参,在函数体中交换指针变量所指内存中存储的数据;
(4)使用随机数生成器确定交换发生的次数,选择每轮要执行的交换方法;
(5)使用while循环语句控制交换进行的轮数;
(6)使用switcj语句产生的随机数选择本文轮执行的交换方法。
代码实现:

#include <stdio.h>
#include <stdlib.h>
//函数声明
void exc1(int l, int r);
void exc2(int* l, int* r);
void exc3(int* l, int* r);

//游戏模拟
//使用随机函数获取交换的次数,和每次交换所选择的函数
int main()

	int a = 0, i = 0, j;
	int l = 1, r = 0;
	srand((unsigned int)time(0));
	i = 5 + (int)(rand() % 5);
	j = i;
	printf("a:%d,i:%d\\n",a,i);
	printf("原始状态:\\n");
	printf("l=%d,r=%d\\n\\n", l, r);
	while (i>0)
	
		i--;
		a = 1 + (int)(rand() % 3);
		switch (a)
		
		case 1:
			exc1(l, r);
			printf("exc1-第%d次交换后的状态\\n", j - i);
			printf("l=%d,r=%d\\n\\n", l, r);
			break;
		case 2:
			exc2(&l, &r);
			printf("exc2-第%d次交换后的状态\\n", j - i);
			printf("l=%d,r=%d\\n\\n", l, r);
			break;
		case 3:
			exc3(&l, &r);
			printf("exc3-第%d次交换后的状态\\n", j - i);
			printf("l=%d,r=%d\\n\\n", l, r);
			break;
		default:
			break;
		
	
	return 0;

//函数定义
void exc1(int l, int r)

	int tmp;
	tmp = l;		//交换形参的值
	l = r;
	r = tmp;

void exc2(int* l, int* r)

	int* tmp;
	tmp = l;		//交换形参的值
	l = r;
	r = tmp;

void exc3(int* l, int* r)

	int tmp;
	tmp = *l;		//交换形参变量指向内容的值;
	*l = *r;
	*r = tmp;

运行截图:

三、奇数阶幻方

描述:将从1至n平方的自然数排列成纵横各有n个数的矩阵,使每行每列每条主对角线上的n个数之和都相等。
分析:
(1)矩阵的行数、列数、矩阵中的元素的数量都由n确定,在程序中设置scanf()函数,由用户手动控制魔方的规模。(案例只针对奇数阶的幻方,所以如果输入的数据不是奇数,再使用goto语句回到输入函数之前
(2)元素的数量不确定,所以使用malloc()函数动态申请存储空间;
(3)数据按列优先存储在malloc函数开辟的空间中,在输出时,每输出n个数据进行一次换行;
(4)将所有的操作封装在一个函数中,在主函数中调用该函数,幻方输出之后,使用free()函数释放函数中申请的堆空间。
代码实现:

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>

void array();
int main ()

	array();							//调用array函数
	return 0;

	void array()
		
		int n, i, j, idx, num, MAX;
		int* M;								//定义一个一维数组指针,按行优先存储矩阵中的元素
		printf("请输入n:");
		input:
		scanf("%d", &n);
		if (n % 2 == 0)						//n是偶数,则重新输入
		
			printf("n不为奇数,请重新输入:");
			goto input;
		
		MAX = n*n;							//MAX为幻方中的最大值,也是元素个数
		M = (int*)malloc(sizeof(int)*MAX);	//分配存储空间
		M[n / 2] = 1;						//获取数值1的列标
		i = 0;
		j = n / 2;
		//从2开始确定每个数的存放位置
		for (num = 2; num <= MAX; num++)
		
			i = i - 1;
			j = j + 1;
			if ((num - 1) % n == 0)			//当前数是n的倍数
			
				i = i + 2;
				j = j - 1;
			
			if (i < 0)						//当前数在第0行
				i = n - 1;
			if (j>n - 1)					//当前数在最后一列,即n-1列
				j = 0;
			idx = i*n + j;					//根据二维数组下标与元素的对应关系
											//找到当前数在数组中的存放位置
			M[idx] = num;					
		
		//打印生成的幻方
		printf("生成的%d阶幻方:", n);
		idx = 0;
		for (i = 0; i < n; i++)		
		
			printf("\\n");					//每n个数据为一行
			for (j = 0; j < n; j++)
			
				printf("%3d", M[idx]);
				idx++;
			
		
		printf("\\n");
		free(M);							//手动释放堆空间
	

运行截图:

四、快速排序

#include <stdio.h>

//快速排序
void QuickSort(int *arr, int left, int right)

	//如果数组左边的索引大于或等于右边索引,说明该序列整理完毕
	if (left >= right)
		return;
	int i = left;
	int j = right;
	int key = *(arr + i);			//使用key来保存作为键值的数据
	//本轮排序开始,当i=j时本轮排序结束,将值赋给arr[i]
	while (i < j)
	
		while ((i < j) && (key <= arr[j]))
			j--;					//不符合条件,继续向前寻找
		*(arr + i) = *(arr + j);
		//从前往后找一个大于当前键值的数据
		while ((i < j) && (key >= arr[i]))
			i++;					//不符合条件,继续向后寻找
		//直到i<j不成立时while循环结束,进行赋值
		*(arr + j) = *(arr + i);
	
	*(arr + i) = key;
	QuickSort(arr, left, i - 1);
	QuickSort(arr, i + 1, right);

//输出数组
void print(int *arr, int n)

	for (int i = 0; i < n; i++)
		printf("%d ", *(arr + i));

int main()

	int arr[10] =  3, 5, 6, 7, 2, 8, 9, 1, 0, 4 ;
	printf("原数组:\\n");
	print(arr, 10);
	QuickSort(arr, 0, 9);			//排序算法
	printf("\\n排序后的数组:\\n");
	print(arr, 10);					//输出数组
	return 0;

运行截图:

五、天生棋局

描述:创建棋盘、初始化棋盘、输出棋盘、销毁棋盘。
代码实现:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
int ** createBoard(int n)//用返回类型是二维指针的类型,创建一个棋盘,长度由主函数传递来

	int **p = (int**)calloc(sizeof(int*), n);
	int i = 0;
	for (i = 0; i < n; i++)
	
		p[i] = calloc(sizeof(int), n);
	
	return p;

//初始化棋盘
int initBoard(int **p, int n, int tmp)//用随机数下棋

	int i, j;
	int t = tmp;
	while (t > 0)
	
		i = rand() % n;
		j = rand() % n;
		if (p[i][j] == 1)//坐标内已有棋子则再次循环
			continue;
		else
		
			p[i][j] = 1;
			t--;
		
	
	return 0;

//输出棋盘
int printfBoard(int **p, int n)

	int i, j;
	for (i = 0; i < n; i++)//用行列计数变量检测同一行或列是否多于2个棋子
	
		for (j = 0; j < n; j++)
		
			if (p[i][j] == 1)						//输出棋子
			
				printf("●");
			
			else									//搭建棋盘
			
				if (i == 0 && j == 0)
					printf("┏");
				else if (i == 0 && j == n - 1)
					printf("┓");
				else if (i == n - 1 && j == 0)
					printf("┗");
				else if (i == n - 1 && j == n - 1)
					printf("┛");
				else if (j == 0)
					printf("┠");
				else if (i == n - 1)
					printf("┷");
				else if (j == n - 1)
					printf("┨");
				else if (i == 0)
					printf("┯");
				else
					printf("┼");
			
		
		putchar('\\n');
	
	for (i = 0; i < n; i++)//用行列两个循环判断是否行列上有两个相邻的棋子
	
		for (j = 0; j<n; j++)
		
			if (p[i][j] == 1)
			
				if (j>0 && p[i][j - 1] == 1)		//判断同一行有无相邻棋子
				
					printf("好棋!\\n");
					return 0;
				
				if (i > 0 && p[i - 1][j] == 1)		//判断同一列有无相邻棋子
				
					printf("好棋\\n");
					return 0;
				
			
		
	
	printf("不是好棋\\n");
	return 0;

//销毁棋盘
void freeBoard(int **p, int n)

	int i;
	趣味C语言

趣味C语言

矩阵转置

10:矩阵转置

MATLAB在数学建模中的应用

1170. 重塑矩阵