我接到了一個用 C 語言撰寫的學校作業,以創建一個乘以矩陣的程式。我將在下面列出分配限制,這樣人們就不會回答關于我為什么這樣做的問題。導師限制:
- 不能在代碼中的任何地方使用方括號(改用指標表示法)
- 矩陣 A、B、C 必須是單個整數指標變數(int *A、*B、*C)
- 只能使用main函式和header指定的函式
- 必須用“gcc -ansi -Wall -o p2 p2.c”編譯
我還沒有實作矩陣乘法函式,因為我遇到的問題與檔案讀取或記憶體分配有關。
我遇到的具體問題是,當我使用 malloc 或 calloc(都嘗試過)為指標矩陣分配空間時,程式會在輸出的某些位置插入 33 而不是 0。此時我已經嘗試了所有方法,并且確信我對指標的了解從根本上是有缺陷的。
p2.h(由講師提供)
#include <stdio.h>
#include <stdlib.h>
/* This function reads m, n, and p from the datafile.
It then allocates the correct amount of memory required for matrices
A, B, and C.
Then matrices A and B are filled from the datafile.
The values for m, n, and p are passed by reference, and are
thus filled in by this function
PARAMETERS in order are:
int ** matrix A
int ** matrix B
int ** matrix C
int * m The number of rows in matrix A
int * n The number of columns in matrix A and
The number of rows in matrix B
int * p The number of columns in matrix B
char * The name of the datafile, from the command line
*/
void read_matrices(int **, int **, int **, int *, int *, int *, char *);
/* This function prints a matrix. Rows and columns should be preserved.
PARAMETERS in order are:
int * The matrix to print
int The number of rows in the matrix
int The number of columns in the matrix
*/
void print_matrix(int *, int, int);
/* The two matrices A and B are multiplied, and matrix C contains the
result.
PARAMETERS in order are:
int * Matrix A
int * Matrix B
int * Matrix C
int m
int n
int p
*/
void mult_matrices(int *, int *, int *, int, int, int);
p2.c(很抱歉進行了大量除錯,弄得一團糟)
#include <stdio.h>
#include <stdlib.h>
#include "./p2.h"
/* constants for testing */
#define cM 3
#define cN 2
#define cP 5
int main(int argc, char **argv) {
if (argc < 2) {
printf("Must include an argument.\n");
exit(1);
}
char *path = *(argv 1);
int *m = (int *) malloc(sizeof(int));
int *n = (int *) malloc(sizeof(int));
int *p = (int *) malloc(sizeof(int));
*m = cM; *n = cN; *p = cP;
int i,j; /* loop counters */
/* allocate space for 2d pointer arrays */
int **A = NULL;
A = (int **) malloc(*m * sizeof(int *));
for (i = 0; i < *m; i ) {
*(A i) = (int *) malloc(*n * sizeof(int));
}
int **B = NULL;
B = (int **) malloc(*n * sizeof(int *));
for (i = 0; i < *n; i ) {
*(B i) = (int *) malloc(*p * sizeof(int));
}
int **C = NULL;
C = (int **) malloc(*m * sizeof(int *));
for (i = 0; i < *m; i ) {
*(C i) = (int *) malloc(*p * sizeof(int));
}
/* write data to A */
for (i = 0; i < *m; i ) {
for (j = 0; j < *n; j ) {
*(*(A i) j) = 0;
}
}
/* testing a */
for (i = 0; i < *m; i ) {
for (j = 0; j < *n; j ) {
if (*(*(A i) j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
/* write data to B */
for (i = 0; i < *n; i ) {
for (j = 0; j < *p; j ) {
*(*(B i) j) = 0;
}
}
/* testing b */
for (i = 0; i < *n; i ) {
for (j = 0; j < *p; j ) {
if (*(*(B i) j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
/* write data to C */
for (i = 0; i < *m; i ) {
for (j = 0; j < *p; j ) {
*(*(C i) j) = 0;
}
}
/* testing c */
for (i = 0; i < *m; i ) {
for (j = 0; j < *p; j ) {
if (*(*(C i) j) != 0) {
printf("[x]");
} else {
printf("[0]");
}
}
}
printf("\n");
printf("Matrix A: \n");
print_matrix(*A, *m, *n);
printf("Matrix B: \n");
print_matrix(*B, *n, *p);
printf("Matrix C: \n");
print_matrix(*C, *m, *p);
return 0;
}
void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *path) {
FILE *fptr;
fptr = fopen(path, "r");
if (fptr == NULL) {
printf("Cannot open file: ./p2 [filename].txt\n");
exit(1);
}
/* get first 3 numbers from file, set m,n,p */
*m = fgetc(fptr);
fgetc(fptr);
*n = fgetc(fptr);
fgetc(fptr);
*p = fgetc(fptr);
fgetc(fptr);
/* read first matrix */
/* 1) calculate matrix size m x n
* 2) loop through malloc'ed matrix
* 3) each loop, insert char in loc
* 4) if next char NOT 10/32, add nextchar*10 to value in loc
*/
char cur;
while ( (cur = fgetc(fptr)) != EOF ) {
if (cur == 10 || cur == 32) {
/* do nothing :) */
} else {
*m = cur;
*n = cur;
*p = cur;
break;
}
}
printf("m: %c\n", *m);
printf("n: %c\n", *n);
printf("p: %c\n", *p);
printf("next: %c\n", fgetc(fptr));
fclose(fptr);
}
void print_matrix(int *X, int rows, int cols) {
int r, c;
int k = 0;
for (r = 0; r < rows; r ) {
for (c = 0; c < cols; c ) {
printf("\t%d", *(X k));
k ;
}
printf("\n");
}
}
void mult_matrices(int *A, int *B, int *C, int m, int n, int p) {
}
d2.txt(資料檔案)
3
2
4
1 2
3 4
5 6
7 8 9 10
11 12 13 14
輸出:./p2 d2.txt
[0][0][0][0][0][0]
[0][0][0][0][0][0][0][0][0][0]
[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
Matrix A:
0 0
0 0
0 0
Matrix B:
0 0 0 0 0
0 33 0 0 0
Matrix C:
0 0 0 0 0
0 33 0 0 0
0 0 0 0 33
如果你注意到,我有一些除錯代碼檢查陣列中的當前項是否為0。似乎表明它們都是0,讓我覺得這是一個列印問題,但我更迷失在什么會造成這種情況。33 的 ascii 代碼是一個感嘆號,但我不確定它有什么相關性。
uj5u.com熱心網友回復:
根據您應該使用的函式簽名,您需要使用正確的索引數學將二維陣列實作為一維陣列。這將導致所有記憶體被連續布置,這完全不能保證你現在分配記憶體的方式(malloc每個矩陣兩次呼叫)。例如:
#include <stdio.h>
#include <stdlib.h>
void print_matrix(int* A, int rows, int cols)
{
for (int r=0; r<rows; r )
{
for (int c=0; c<cols; c )
{
// If you want to treat A as a 2D matrix, this is where we have to do a bit of
// fancy index math to give you what double bracket notation [][] does for you
// r * cols gives you the index of the right row
// c give you the column offset in that row
// add that offset to A then dereference
printf("%d\t", *(A (r * cols c)));
}
printf("\n");
}
}
int main(void)
{
// matrix A is supposed to be m by n
int* A;
// read these from file, or where ever they're supposed to come from
int m = 2;
int n = 10;
// Allocate the memory in one chunk. This makes the memory all contiguous, just the
// same as if you had done A[m][n]. However, the double call malloc for each int**
// matrix probably will not give you contiguous memory for the entire matrix. Each
// call to malloc is independent.
A = malloc(m * n * sizeof(int)); // or sizeof(*A) would be even better
if (A == NULL)
{
// handle error
}
// We can initialize values for A at this point, still not needing to care about
// rows or columns
for (int i=0; i<m*n; i )
{
*(A i) = i; // using i for a better visual when we print
}
print_matrix(A, m, n);
free(A);
return 0;
}
演示
uj5u.com熱心網友回復:
你把簡單的事情復雜化了。使用指向陣列的指標并分配二維陣列。
使用正確型別的大小變數。
盡量避免副作用。使用引數和函式回傳值。
//this function is for the test purposes only
int writefile(const char *fn)
{
FILE *fo = fopen(fn, "w");
fprintf(fo,
"3\n"
"2\n"
"4\n"
"1 2\n"
"3 4\n"
"5 6\n"
"7 8 9 10\n"
"11 12 13 14\n");
fclose(fo);
}
void *allocIntMatrix(size_t rows, size_t cols)
{
int (*m)[cols] = malloc(rows * sizeof(*m));
return m;
}
void printIntMatrix(size_t rows, size_t cols, int (*m)[cols])
{
for(size_t row = 0; row < rows; row )
{
for(size_t col = 0; col < cols; col )
{
printf("[]] ", m[row][col]);
}
printf("\n");
}
}
int readData(FILE *fi, size_t rows, size_t cols, int (*m)[cols])
{
for(size_t row = 0; row < rows; row )
{
for(size_t col = 0; col < cols; col )
{
fscanf(fi, "%d", &m[row][col]);
}
}
return 0;
}
int main(int argc, char **argv)
{
size_t n,m,p;
writefile("a.aaa");
FILE *fi = fopen("a.aaa", "r");
fscanf(fi, "%zu", &m);
fscanf(fi, "%zu", &n);
fscanf(fi, "%zu", &p);
printf("n = %zu, m = %zu, p = %zu\n", n, m, p);
int (*A)[n] = allocIntMatrix(m, n);
int (*B)[p] = allocIntMatrix(n, p);
readData(fi, m, n, A);
readData(fi, n, p, B);
fclose(fi);
printIntMatrix(m, n, A);
printf("\n");
printIntMatrix(n, p, B);
return 0;
}
https://godbolt.org/z/adoEx1r4f
您需要檢查錯誤(檔案、記憶體等)。為了示例的簡單起見,我跳過了它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/364040.html
下一篇:前處理器:宏只展開一次
