so I am trying to figure out how to multiply 2 matrices using pointers. It successfully works the way it is now, but instead of using conventional array access methods, I would like to learn the use of pointers.
Here is my code:
#include <stdio.h>
#include<conio.h>
#include <stdlib.h>
#include <iostream>
/* Routines called. */
int loadMatrixFromFile(char *filename, int *data);
void showMatrix(int *data, int len);
int makeIdent(int matrixB[5][5], int length);
int matrixA[5][5];
int matrixB[5][5];
int matrixC[5][5];
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]);
int main(){
int len, data[1000];
len = loadMatrixFromFile("Numbers.txt", data);
showMatrix(data, len);
makeIdent(matrixB,len);
multiplyMatrices(matrixA, matrixB, matrixC);
}
int makeIdent(int matrixB[5][5], int len){
int i,j;
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
matrixB[i][j]=1;
printf("%d ",matrixB[i][j]);
}
else{
matrixB[i][j]=0;
printf("%d ",matrixB[i][j]);
}
}
printf("\n");
}
return matrixB[i][j];
printf("\n");
}
int loadMatrixFromFile(char *filename, int *data){
FILE *in;
int len;
int j;
in = fopen(filename, "r");
if (in == NULL) {
printf("Could not find file: %s \n", filename);
}
else {
printf("Reading numbers...\n");
fscanf(in, "%d", &len);
printf("reading %d numbers from file %s ....\n", len, filename);
for(j=0;j<len;j++) {
fscanf(in, "%d", data + j);
}
fclose(in);
}
for(int i = 0; i<5; i++){
for(int j = 0; j < 5; j++){
matrixA[i][j] = *(data + i*5 + j);
}
}
return len;
}
void showMatrix(int *data, int len){
int j;
int count = 0;
printf("Showing %d numbers from data array....\n", len);
printf("Matrix A is: \n");
for(j=0;j<len;j++) {
printf("%d ", *(data + j));
count++;
if(count % 5 == 0){
printf("\n");
}
}
printf("\n");
}
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int count = 0;
printf("\n");
printf("Matrix A x Matrix B is: \n");
for (i = 0; i<5; i++){
for (j = 0; j<5; j++){
matrixC[i][j] = 0;
matrixC[i][j] += matrixA[i][j]*matrixB[i][j];
printf("%d ",matrixC[i][j]);
count++;
if(count % 5 == 0){
printf("\n");
}
}
}
}
Well your algorithm for matrix multiplication is completely wrong.
You say 'I want to learn how to do it with pointers', but here's the thing, you're already are doing it with pointers.
In this code
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
the variables matrixA, matrixB and matrixC are pointers. In C++ it's impossible to have an array for a function parameter. It automatically gets converted to a pointer. It's also true that the syntax for accessing an array is identical to the syntax for accessing a pointer.
If you want to make it explicit that you are using pointers then rewrite your code like this
void multiplyMatrices(int (*matrixA)[5], int (*matrixB)[5],int (*matrixC)[5]){
Now you can see that matrixA, matrixB and matrixC pointers to arrays of 5 integers. You don't have to make any other changes. And in fact this change is exactly what the compiler does when you try to use an array as a function parameter.
Here's a good looking link that explains how pointers and arrays compare. The link talks about C, but the rules are the same in C++. Have a read it will probably help you understand better than I can.
Related
It's a c++ program that takes input for 3*3 matrices and displays the sum and product of those matrices. Now I have improved the program and it's working as expected, so is there anything that can be improved in this program.
#include <stdio.h>
//function prototypes
To get the input for an array.
void getarr(int *x);
To add the two matrices.
void addm(int *x, int *y, int *z);
To print an array.
void displaym(int *x);
To multiply two arrays.
void multm(int *x, int *y, int *z);
main function
int main() {
//declaring arrays for matrices
int a[3][3];
int b[3][3];
int c[3][3];
int d[3][3];
//getting input from user
printf("\nEnter nine numbers as the values for first matrix:\n");
getarr(a[0]);
printf("\nThe matrix you entered is:\n");
displaym(a[0]);
printf("\nEnter nine numbers as the values for second matrix:\n");
getarr(b[0]);
printf("\nThe matrix you entered is:\n");
displaym(b[0]);
//calling function for addition
addm(a[0], b[0], c[0]);
//calling function for multiplication
multm(a[0], b[0], d[0]);
//printing the matrices
printf("\nThe sum of the matrices is:\n");
displaym(c[0]);
printf("\nThe product of the matrices is:\n");
displaym(d[0]);
return 0;
}
definition of functions
void getarr(int *x) {
for (int j = 0; j < 9; j++) {
printf("%d:", j);
scanf("%d", x);
x++;
}
}
void addm(int *x, int *y, int *z) {
for (int i = 0; i < 9; i++) {
*z = *x + *y;
z++;
x++;
y++;
}
}
void multm(int *x, int *y, int *z) {
for(int j=0;j<3;j++){
for (int i = 0; i < 3; i++, z++) {
*z = (*x++)*(*y)+(*x++)**(y + 3)+(*x)**(y + 6);
x -= 2, y += 1;
}
x += 3, y -= 3;
}
}
void displaym(int *x) {
printf("\n\n");
for (int i = 0; i < 9; i++) {
printf("%d ", *x++);
if (i == 2 || i == 5)
printf("\n");
}
}
The is a common error for uninitialized pointers. You declared int * d; earlier in the program but you never give it a memory that d should point to. And you need to initialize that memory.
You can add the following line inside main but before any use of d,
d = new int[9];
memset(d, 0, 9);
I'm trying to find the sum of the numbers in a char array.
My code works for most cases. Example : a=dasn344wee22ee, the output is:366 - which is good
But when my char is,for example : andre54e5 the output should be 59, but the program displays: 108.
Can anybody tell me what the issue is?
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
using namespace std;
int getnr(char a[], int i, int j)
{
int counter = 0;
char sir[1000];
for (int x = i; x<j; x++)
{
sir[counter] = a[x];
counter++;
}
return atoi(sir);
}
int main()
{
char a[1000];
int s = 0, inceput, finals;
cin.getline(a, 255);
for (int i = 0; i<strlen(a); i++)
{
if (isdigit(a[i]) )
{
if (i == strlen(a) - 1)
{
s += getnr(a, i, strlen(a));
}
for (int j = i + 1; j<strlen(a); j++)
{
if (!isdigit(a[j]) || j == strlen(a) - 1)
{
s += getnr(a, i, j + 1);
i = j;
break;
}
}
}
}
cout << s;
return 0;
}
In your function int getnr(char a[], int i, int j), you forgot to null-terminate string sir, such that atoi(sir) might yield a garbage value (actually the behaviour is undefined). The following should help:
int getnr(char a[], int i, int j)` {
...
sir[counter] = '\0';
return atoi(sir);
}
The problem is that getnr() doesn't add a null terminator to the sir array, so you're getting undefined behavior when you call atoi(sir).
int getnr(char a[], int i, int j)
{
int counter = 0;
char sir[1000];
for (int x = i; x<j; x++)
{
sir[counter] = a[x];
counter++;
}
sir[counter] = '\0';
return atoi(sir);
}
The issue is within this part of code:
if (i == strlen(a) - 1)
{
s += getnr(a, i, strlen(a));
}
Specifically, if your last number is a single digit (which it is), it will always return junk.
So, I would change to only convert the single char of the char array as a digit and at it to the int s.
Edit:
For some reason when doing s+= a[i], I return junk.
But, doing the following, does the trick:
if (i == strlen(a) - 1)
{
string x;
x[0] = a[i];
int l = stoi(x);
s += l;
}
I know that there's a much more effective way, but I'm not sure why s+= a[i] itself returns false numbers.
i am realsing qsort algorithm, according on Korman. But there is infinite computation, when i trying to start it. I suppose, that problem is in partition. My programms reads from file, first number in file-line is counting of numbers to sort, and next go all numbers
#include <stdio.h>
#include <stdlib.h>
int swap(int &a, int &b);
int sorting(int *array, int &b, int &l);
int partition(int *array ,int &begin, int &last);
int main()
{
FILE* pFile=fopen("input.txt", "r");
//fopen("input.txt", "r");
//fopen("output.txt", "w");
int n;
int begin=0;
fscanf(pFile, "%d", &n);
int* array=(int*)malloc(n*sizeof(int));
for (int i=0; i<n; ++i)
fscanf(pFile,"%d", &array[i]);
int n1=n-1;
sorting(array, begin, n1);
printf("JJJJ");
for (int i=0; i<n; ++i)
printf("%d ", array[i]);
printf("\n");
fclose(pFile);
free(array);
return 0;
}
int sorting(int* array, int &b, int &l)
{
int pivot,pivot1;
if(b<l)
{
pivot=partition(array, b, l);
printf("MAXMAX321");
int a=pivot-1;
sorting(array, b, a);
printf("MAXMAX123");
pivot1=pivot+1;
sorting(array, pivot1, l);
printf("MAXMAX");
}
return 0;
}
int partition(int* array, int &b, int &l)
{
int x=array[b];
int i=b;
int j=l;
while(true)
{
while(array[j]>x){
printf("AHAH");
--j;
}
while(array[i]<x){
printf("AZAZA");
++i;
}
if(i<j)
swap(array[i],array[j]);
else
return j;
}
}
int swap(int &x, int &y)
{
x=x+y;
y=x-y;
x=x-y;
return 0;
}
Thank you in advance.
This part is very dangerous code:
while(true)
{
while(array[j]>x){
printf("AHAH");
--j;
}
while(array[i]<x){
printf("AZAZA");
++i;
}
if(i<j)
swap(array[i],array[j]);
else
return j;
}
Avoid while (true) as much as possible, except on very special case you should have a clear condition stated in the loop. Here it is the one that leads to `return. It will clarify the goal of the loop.
When testing array value like while(array[i]<x) compare i to the array size before ! You're never sure that you condition will always be met in the array, ensure you have a safety belt.
I cannot understand what you are doing in function partition but doing it like this should work:
int partition(int* array, int &b, int &l)
{
int pivot_index = l;//You can take here everything between b and l
//swap(array[l], array[pivot_index]); decomment this if your pivot is between b and l
int current_pos = b;
for(int i = b;i < l - 1; ++i)
if(array[i] <= array[pivot_index])
swap(array[i], array[current_pos++]);
swap(array[l], array[current_pos]);
return current_pos;
}
here is my code of qsort in c++.
#include <stdio.h>
void partition(int* arr, int start, int pivot, int end){
int i=start+1;
for(int j=start+1; j < end; j++){
if (arr[j]<pivot){
int c=arr[i];
arr[i]=arr[j];
arr[j]=c;
i++;
}
}
int c=arr[start];
arr[start]=arr[i-1];
arr[i-1]=c;
}
void qsort(int *arr, int start, int end, int len){
if (len<=1){
// break;
}
else{
int pivot=arr[start];
partition(arr, start, pivot, end);
qsort(arr, start, pivot-1, len-1);
qsort(arr, pivot+1, end, len-1);
}
}
int main(){
int len;
printf("Vvedite kolvo elementov");
scanf("%d", &len);
int *arr=new int[len];
for(int i=0;i<len; i++){
printf("\n Vvedite %d element", i);
scanf("%d", &arr[i]);
}
qsort(arr, 0, len, len);
for(int i=0; i<len; i++){
printf(" %d, ", arr[i]);
}
delete [] arr;
return 0;
}
But it has very strange output. For example - it works ok on "5 1 2 4 3" and sorts it, but when i for example type "998 603 805 990 900" that in theory absolutly the same for computer, it prints all 0.
Any suggestions on how to identify/fix the problem are greatly appreciated.
Hey guys I am trying practice learning pointers in c++. So I am trying to multiply these arrays and am getting all 0's in my resulting matrix. if anybody could just hint to me what to look at or some advice on what is causing this that would be amazing.
Here is the code:
#include <stdio.h>
#include<conio.h>
#include <stdlib.h>
#include <iostream>
/* Routines called. */
int loadMatrixFromFile(char *filename, int *data);
void showMatrix(int *data, int len);
int makeIdent(int matrixB[5][5], int length);
int matrixA[5][5];
int matrixB[5][5];
int matrixC[5][5];
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]);
int main(){
int len, data[1000];
len = loadMatrixFromFile("Numbers.txt", data);
showMatrix(data, len);
makeIdent(matrixB, len);
multiplyMatrices(matrixA, matrixB, matrixC);
}
int makeIdent(int matrixB[5][5], int len){
int i,j;
int *ptr;
ptr = &matrixB[5][5];
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
*ptr=1;
printf("%d ", *ptr);
}
else{
*ptr=0;
printf("%d ",*ptr);
}
}
printf("\n");
}
return *ptr;
printf("\n");
}
int loadMatrixFromFile(char *filename, int *data){
FILE *in;
int len;
int j;
in = fopen(filename, "r");
if (in == NULL) {
printf("Could not find file: %s \n", filename);
}
else {
printf("Reading numbers...\n");
fscanf(in, "%d", &len);
printf("reading %d numbers from file %s ....\n", len, filename);
for(j=0;j<len;j++) {
fscanf(in, "%d", data + j);
}
fclose(in);
}
for(int i = 0; i<5; i++){
for(int j = 0; j < 5; j++){
matrixA[i][j] = *(data + i*5 + j);
}
}
return len;
}
void showMatrix(int *data, int len){
int j;
int count = 0;
printf("Showing %d numbers from data array....\n", len);
printf("Matrix A is: \n");
for(j=0;j<len;j++) {
printf("%d ", *(data + j));
count++;
if(count % 5 == 0){
printf("\n");
}
}
printf("\n");
}
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int *ptr1, *ptr2, *ptr3;
ptr1 = &matrixA[5][5];
ptr2 = &matrixB[5][5];
ptr3 = &matrixC[5][5];
printf("\n");
printf("Matrix A x Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
*ptr3=0;
}
}
for (i = 0; i<5; i++){
for (j = 0; j<5; j++){
for(n=0;n<5;n++){
*ptr3 += (*ptr1**ptr2);
}
printf("%d ",*ptr3);
}
printf("\n");
}
}
In makeIdent you need to increment ptr after each element. To
initialize ptr you need to point it to the first element in the array, not the last element.
int makeIdent(int matrixB[5][5], int len){
int i,j;
int *ptr;
ptr = &matrixB[0][0]; // note the 0 instead of the 5
printf("Matrix B is: \n");
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==j){
*ptr=1;
printf("%d ", *ptr);
}
else{
*ptr=0;
printf("%d ",*ptr);
}
ptr++; // this is new
}
printf("\n");
}
return 0;
}
This is closer to what you want for multiplyMatrices:
void multiplyMatrices(int matrixA[5][5], int matrixB[5][5],int matrixC[5][5]){
int i, n, j;
int *ptr1, *ptr2, *ptr3;
ptr1 = &matrixA[0][0];
ptr2 = &matrixB[0][0];
ptr3 = &matrixC[0][0];
for (i = 0; i<5; i++) {
for (j = 0; j<5; j++) {
*ptr3 = (*ptr1 * *ptr2);
ptr1++; ptr2++; ptr3++;
}
}
}
You could say this instead:
*ptr3++ = *ptr1++ * *ptr2++;
But I don't want to confuse the issue.