1. 程式人生 > >任意行列二維陣列C語言實現

任意行列二維陣列C語言實現

    在C語言中,陣列是一個連續的線性儲存結構,陣列名稱即為陣列首元素首地址,中括號被C語言解釋為指向運算,通過對指標的加法,實現取得相應元素。對二維陣列的使用則相當於定義一個二階指標,可以看做是一個一維數組裡每一個成員是一個一維陣列,所以二維陣列的名字就是一個指向指標的指標,即二階指標。通過兩次指向運算得到相應的元素。

    但是在C語言中,對變數空間的申請必須要寫在一個函式的所有有效語句之前,使得無法得到使用者自定義的陣列,如果想更改二維陣列的行列值不得不更改原始碼,具體方式見示例1;

    這種方式顯然不符合任意行列二維陣列的要求,那麼我們想到,既然前面提到二維陣列的本質是一個二階指標,那麼,我們是否可以通過用malloc()函式動態申請空間,然後把動態申請的空間的首地址賦值給一個一維陣列的每一個元素。但是這樣做同樣存在問題,我們只能確定二維陣列的”列“,並不能確定它的”行“。想要修改行值,依然需要更改原始碼。具體程式碼見示例2;

    所以,想要實現任意行列二維陣列,就必須拋棄之前的二階指標的概念,因為,在C語言中,能夠動態申請的空間只能通過malloc()或calloc()函式實現,而它們的返回值都只是(void *)型別的,為一階指標。因為就算C語言給出了能夠申請二維陣列的函式,能夠返回二階指標,那如果我想生成一個三維陣列怎麼辦呢,難不成還要給一個返回值為三階指標的函式麼,那如果是n維陣列呢......所以我們就必須考慮用一維陣列來處理二維陣列。其實這也是符合計算機的基本原理的,因為在計算機中記憶體就是一個二維線性的儲存空間,我們看到的二維陣列以及二階指標都是經過C語言處理過的”假象“!既然C語言能夠完成,我們自然也可以通過一個簡單的數學公式實現用一維陣列實現任意行列二維陣列。

    數學公式基礎:1、一個矩陣的元素個數 = 行值 * 列值;

                             2、一個n行m列的矩陣的第i行第j列的元素,為該矩陣的第(i - 1) * n + j個元素(i <= n, j <= m);

    有了這個數學基礎,再多考慮C語言中陣列下標從零開始這一特點,我們就可以輕鬆地編寫出能夠實現任意行列的二維陣列的程式碼!

    由於二維陣列不一定只在一個程式中使用。於是我們編寫一個.h檔案,將初始化二維陣列,以及對它的操作的函式寫進去,使得以後我們的程式需要用到二維陣列的時候只需要在程式的前面加上#include“*.h”即可。

    由於二維陣列不一定存放int型別的資料或者某一種特定的資料,有可能是其他型別或者是使用者自己定義的結構體型別。因此,在該.h檔案裡,給出了一個USER_TYPE型別,這就要求在引用該.h檔案之前必須先做一個操作。即使用typedef讓USER_TYPE成為自己想要的通過二維陣列儲存的資料型別。

    在之前所說的使用USER_TYPE儲存資料,那麼便出現了另一個問題,即,無法編寫輸出該陣列的函式,我們不能通過一個簡單的printf("%d", USER_TYPE);來輸出這一型別,如果USER_TYPE是結構體型別,我們就無法輸出了。這裡我們通過指向函式的指標來解決,要求使用者必須編寫一個能夠輸出一個自己定義的USER_TYPE型別的資料的函式,在使用我們.h檔案裡編寫的二維陣列的輸出函式的時候,將自己編寫的函式的名稱作為引數傳遞過去,而輸出二維陣列的函式在編寫時只需要關注二維陣列的整體性輸出,每一次的輸出,只需要通過形參裡的函式指標變數即可,至於該函式是如何輸出的,這是使用我們提供的.h檔案的人所需要關心的。

    本文章所給的主函式並不具有實際意義,只是對於dyadicArray.h內的函式的呼叫和測試。

    具體程式碼如下:

錯誤示例1:
#define MAX_ROW     3
#define MAX_COL     4

void main(void) {
    dyadicArray[MAX_ROW][MAX_COL];
}
錯誤示例2:
#include<malloc.h>

#define MAX_ROW

void main(void) {
    int *dyadicArray[MAX_ROW];
    int maxCol;    

    printf("請輸入您要得到的陣列的列數:");
    scanf("%d", &maxCol);
    for(i = 0; i < MAX_ROW; i++) {
        dyadicArray[i] = (int *)malloc(sizeof(int) * maxCol);
    }
}
正確程式碼:
//dyadicArray.h#ifndef _DYADIC_ARRAY_H_ #define _DYADIC_ARRAY_H_typedef struct DYADIC_ARRAY{  int row;  int col;  USER_TYPE *array; }DYADIC_ARRAY;void initDyadicArray(DYADIC_ARRAY **arrayHead, int row, int col); USER_TYPE *getElementByIndex(DYADIC_ARRAY array, int row, int col); void showDyadicArray(DYADIC_ARRAY root, void (* printUserType)(USER_TYPE));void initDyadicArray(DYADIC_ARRAY **arrayHead, int row, int col) {  *arrayHead = (DYADIC_ARRAY *)calloc(1, sizeof(DYADIC_ARRAY));  (*arrayHead)->row = row;  (*arrayHead)->col = col;  (*arrayHead)->array = (USER_TYPE *)calloc(row * col, sizeof(USER_TYPE)); }USER_TYPE *getElementByIndex(DYADIC_ARRAY root, int row, int col) {  return root.array + ((row - 1) * root.col + col - 1 - 1); }void showDyadicArray(DYADIC_ARRAY root, void(*printUserType)(USER_TYPE)) {  int i;  int j; printf("該二維陣列為:\n");  for (i = 0; i < root.row; i++) {   for (j = 0; j < root.col; j++) {    printUserType(root.array[i * (root.col - 1) + j]);    printf(" ");   }   printf("\n");  } } #endif//demoDyadicArray.c#include<stdio.h> #include<malloc.h>typedef struct POINT {  int row;  int col; }POINT, USER_TYPE;#include"dyadicArray.h"void showOnePoint(USER_TYPE aPoint);void showOnePoint(USER_TYPE aPoint) {  printf("(%d, %d)", aPoint.row, aPoint.col); }void main(void) {  DYADIC_ARRAY *head = NULL;  int row;  int col;  USER_TYPE user; user.col = 3;  user.row = 4; printf("請分別輸入二維陣列的行和列:");  scanf_s("%d%d", &row, &col); initDyadicArray(&head, row, col);  showDyadicArray(*head, showOnePoint);  *(getElementByIndex(*head, 2, 3)) = user;  showDyadicArray(*head, showOnePoint); fflush(stdin);  getchar(); }

相關推薦

任意行列陣列C語言實現

    在C語言中,陣列是一個連續的線性儲存結構,陣列名稱即為陣列首元素首地址,中括號被C語言解釋為指向運算,通過對指標的加法,實現取得相應元素。對二維陣列的使用則相當於定義一個二階指標,可以看做是一個一維數組裡每一個成員是一個一維陣列,所以二維陣列的名字就是一個指向指標的

C語言分配動態陣列(結構體實現)

#include<stdio.h> #include<stdlib.h> typedef struct { double **mat; int m; int n; }Matrix; void InitialMatrix(Matrix *T,in

最小乘法的C語言實現

1.  前言 最近斷斷續續重溫了一些數學書,有高等數學,也有初等數學。 有時候,覺得數學才是世界上最美的東西,但有時候又覺得數學很高冷,不接地氣。 不過,前段時間工作中用到了最小二乘法,下面記錄一些用法。 2. 最小二乘法 根據維基百科的說明: 最小二乘法(又稱最小平

關於dp01揹包問題的幾點理解(陣列,java實現

01揹包問題: 給定N種物品和一個揹包。物品i的重量是weight[i],其價值value[i] (i<=N),揹包的容量為M。問應該如何選擇裝入揹包的物品,使得裝入揹包的物品的總價值為最大?在選擇物品的時候,對每種物品i只有兩種選擇,即裝入揹包或不裝入

樹和叉樹 C語言實現

1、基本概念 樹是樹型結構的簡稱,它是一種重要的非線性資料結構。 樹的表示:通常使用廣義表表示方法,即每棵樹的根作為由子樹構成的表的名字而放在表的前面,如下圖的樹對應的廣義表表示為: A(B(D,E(H,I),F),C(G)) 結點的度:樹中每個結點具有的非空子樹數或者說

php 陣列時間排序實現程式碼

function arraySort($arr, $keys, $type = 'asc') {   &nb

力扣992.K個不同整數的子陣列-C語言實現

## 題目 [原題連結](https://leetcode-cn.com/problems/subarrays-with-k-different-integers) 給定一個正整數陣列 A,如果 A 的某個子陣列中不同整數的個數恰好為 K,則稱 A 的這個連續、不一定獨立的子陣列為好子陣列。 (例如,[1,

c語言實現用指標遍歷陣列

1 #include <stdio.h> 2 void bian(int row,int col,int *a) 3 { 4 int i,j; 5 for(i=0;i<row;i++) 6 for(j=0;j<col;j++) 7

ACMNO.24 C語言-轉置矩陣 寫一個函式,使給定的一個陣列(3×3)轉置,即行列互換。 輸入 一個3x3的矩陣 輸出 轉置後的矩陣 樣例

題目描述 寫一個函式,使給定的一個二維陣列(3×3)轉置,即行列互換。 輸入 一個3x3的矩陣 輸出 轉置後的矩陣 樣例輸入 1 2 3 4 5 6 7 8 9 樣例輸出 1 4 7 2 5 8 3 6 9 來源/分類 C語言

C語言對矩陣的轉制與陣列行列互換

 //矩陣的轉制就是二維陣列的行列互換,比如有這樣的一個矩陣a[3][3]=   1,2,3                                                                                           

C語言動態陣列實現矩陣的相乘

c語言動態二維陣列實現矩陣相乘 如何申請動態二維陣列,程式碼如下 該方法是最靈活的,可以任意指定行數和列數 /* *申請a陣列的記憶體* */ /*先申請每一行指標的記憶體*/ a =

C語言陣列解魔方陣

解題思路: 魔方陣的排列規律如下(思路來自網際網路): 注意:剛開始我也沒看懂,但是相信我多看幾遍理解已經能看懂的。 如3×3的魔方陣:      8   1   6  &nbs

C語言 函式返回一位陣列陣列

方法一: 萬能的結構體:構造陣列的結構體,將函式型別定義為此型別 但是考試的時候應該不太方便寫結構體,寫不下也會很麻煩,故介紹方法二 方法二: 指標傳遞: 1、返回一維陣列 例子:將陣列每一位加一: #include<stdio.h> #define N 10 int

C語言】一陣列陣列與指標

一維陣列和指標: 1、一維陣列名: 對於這樣的一維陣列:int a[4];  a作為陣列名就是我們陣列的首地址, a是一個地址常量 .  首先說說常量和變數的關係, 對於變數來說, 用箱子去比喻再好不過了, 宣告一個變數就宣告一個箱子,比如我們開闢出一個蘋果型別的箱子, 給這個變

C語言-----陣列

二維陣列的建立,初始化,使用。 (一)二維陣列的建立 二維陣列定義的一般形式:型別說明符 陣列名[常量表達式][常量表達式] 舉例如下: int a[3][4]; //定義a為 3*4(3行4列) 的陣列。 二位陣列又可以看作是一種特殊的一維陣列:它的元素又是一個一維陣列

C語言中一陣列陣列

int arr [4]  //定義了一個一維陣列,長度為4;說明以下三個分別是什麼型別; (1)arr //型別為int *,表示陣列元素首地址,即圖中箭頭指向的位置。 (2)arr+1 //型別為int *,表示陣列元素首地址+1,即圖中箭頭指向的位置。 (3)arr [0

c語言 將一個陣列行和列的元素互換,存到另一個陣列

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C語言陣列指標練習

描述 程式填空,使其輸出結果是: 1,2,3,4, 10,12,14,16, 18,20,11,12, #include <iostream> using namespace std; void Double(int * p, int n) { for(int i = 0;i

某月天數問題(1.if語句實現 2.陣列實現)(c++)

【題目描述】 從鍵盤輸入某年某月,程式設計輸出該年的該月擁有的天數 【題目難點】 閏年定義: (1)能被4整除,卻不能被100整除 (2)能被400整除 程式碼1:(用if簡單語句來完成) #include <iostream> using na

C語言筆記--利用陣列輸出楊輝三角形

楊輝三角形又稱帕斯卡三角形,其餘的話就不多說,先看下面的三角形:                                 &nb