Skip navigation.
 
mlMultidimensional C arrays as OBJ-C method args: partial solution with compiler warning
FROM : Bob Savage
DATE : Wed Jan 02 23:28:19 2002

I have a test program which gets around the limitation of passing
multidimensional C arrays as arguments to Objective-C methods (as I
described in my earlier message), but not without generating a compiler
warning. For the curious, desperate, or helpful, I present the fruit of my
labor:

/////////////////////////////////////////////////////////////////

//  main.m
//  arrayTEST
//
//  testing what I can do as far as passing
//  C-type arrays as parameters to methods
//
//  <email_removed>

#import <Foundation/Foundation.h>
#import "CArrayTester.h"

int main (int argc, const char * argv[]) {
    int i, j;
    float simple[3];
    float multidimensional[4][3];
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    CArrayTester *aTester = [[CArrayTester alloc] init];
   
    // The things I want to prove, from easy to hard
    // - [1]    I can pass a float
    // - [2]    I can pass an array of type float
    // - [3]    I can pass a multidimensional array of type float
   
    // [1]
    printf("\nPassing a float to a method\n");
    printf("\tbefore: %.3f\n", [aTester floatValue]);
    [aTester setFloatValue:21.12];
    printf("\tafter: %.3f\n", [aTester floatValue]);
   
    // [2]
    printf("\nPassing an array of floats to a method\n");
    simple[0] = 11.2;
    simple[1] = 12.1;
    simple[2] = 21.1;
    // compare the size in main to the size from within a method
    printf("  (ANSI C understands the size of the simple array to be this:
%d)\n", (int)sizeof(simple));
    [aTester setFloatValueByTotalingArray:simple ofSize:3];
    printf("\tafter: %.3f\n", [aTester floatValue]);

    // [3]
    printf("\nPassing a multidimensional array of floats to a method\n");
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            multidimensional[i][j] = (i + ( (float)j/10 ));
        }
    }
    // compare the size in main to the size from within a method
    printf("  (ANSI C understands the size of the multidimensional array to
be this: %d)\n", (int)sizeof(multidimensional));
    // here I can jump to an arbitrary spot using pointer arithmetic
    printf("  The element at [2][1] has a value of %.3f\n",
*(*multidimensional+1)+2);
   
    // the following line behaves as expected, but generates a compiler
warning:
    //    "passing arg 1 of
'setFloatValueByTotallingArrayPointer:ofSize:andStride:' from incompatible
pointer type"
    //
    [aTester setFloatValueByTotalingArrayPointer:multidimensional ofSize:4
andStride:3 ];
   
    printf("\tafter: %.3f\n", [aTester floatValue]);
   
    [pool release];
    return 0;
}

/////////////////////////////////////////////////////////////////

//
//  CArrayTester.h
//  arrayTEST
//
//  Created by Bob Savage on Wed Jan 02 2002.
//  Copyright (c) 2001 Project Steam Weasel. Do with it as thou wilt.
//

#import <Foundation/Foundation.h>


@interface CArrayTester : NSObject {
    float f;
}

// float
-(void)setFloatValue:(float)newFloat;
-(float)floatValue;

// array of floats
//    - size is how many floats
-(void)setFloatValueByTotalingArray:(float *)theArray ofSize:(int)size;

// multidimensional array of floats
//    - size is size of the containing array (how many sub arrays)
//    - stride is the size of the contained array (how many floats)
-(void)setFloatValueByTotalingArrayPointer:(float *)theArray
ofSize:(int)size andStride:(int)stride;

@end

/////////////////////////////////////////////////////////////////

//
//  CArrayTester.m
//  arrayTEST
//
//  Created by Bob Savage on Wed Jan 02 2002.
//  Copyright (c) 2001 Project Steam Weasel. Do with it as thou wilt.
//

#import "CArrayTester.h"


@implementation CArrayTester
-(id)init {
    if(self=[super init]) {
        f = 0.0f;
    }
    return self;
}

-(void)setFloatValue:(float)newFloat {
    f = newFloat;
}

-(float)floatValue {
    return f;
}

-(void)setFloatValueByTotalingArray:(float *)theArray ofSize:(int)size {
    int i;
    int s = sizeof(theArray);
    f = 0; // reset the value before totaling
   
    printf("\tInside -setFloatValueByTotalingArray:ofSize:\n");
    printf("\ta float should have size %d\n", (int)sizeof(float));
    printf("\treceived array with size %d\n", s);
    // note that I don't have any way of knowing how many items
    // the array contains without being told with "size"
   
    for (i = 0; i < size; i++) {
        printf("\t\tvalue of the array at slot [%d] = '%.3f'\n", i,
theArray[i]);
        f+=theArray[i];
    }
}

-(void)setFloatValueByTotalingArrayPointer:(float *)theArray
ofSize:(int)size andStride:(int)stride {
    int i, j;
    int s = sizeof(theArray);
    float total1, total2;
   
    // array size is even further disguised
    printf("\tInside
-setFloatValueByTotalingArrayPointer:ofSize:andStride:\n");
    printf("\treceived array with size %d\n", s);
   
    // the whole thing manually
    total1 = 0;
    for (i = 0; i < size; i++) {
        f = 0; // reset the value before totaling
        for (j = 0; j < stride; j++) {
            printf("\t\tvalue of the array at slot [%d] = '%.3f'\n", i,
theArray[i*stride+j]);
            f+=theArray[i*stride+j];
        }
        total1 +=f;
    }
    f = total1; // set the float value to the sum of the float values
   
    // try it recursively -- as if I had an array of vectors and I wanted to
do something with each vector
    total2 = 0;
    for (i = 0; i < size; i++) {
        f = 0; // reset the value before totaling
        [self setFloatValueByTotalingArray:(theArray+i*stride)
ofSize:stride];
        total2 +=f;
    }
    f = total2; // set the float value to the sum of the float values
    if (!total1 == total2) {
        printf("ERROR! totals do not agree!\n");
    }
    else {
        printf("Success.\n");
    }
}

@end


Related mailsAuthorDate
No related mails found.