I am about to transfer a project I have written in Applescript and Objective C to Excel/VBA/dll. I have started with the Objective C functions that I want to place in a dll and call via VBA.
First of all, I am a statistician who managed to build the original Mac program (a statistical tool that have been very handy to me) through equal amounts of luck, trial and error and perseverance. Please take that into account (also if the answer is embarrassingly obvious). I have used this (minus the 64 bit part) as starting point for the dll: https://sites.google.com/site/jrlhost/links/excelcdll
The Objective C is C with a thin dusting of special Obejctive C code to have it talk with Applescript and the rest of the project so in theory it should be easy to make dlls written in C from it.
But I have already problems with the tiniest of all functions. I am sure it can be done more effectively but right now I need to know WHY it doesn´t work if I am ever going to be able to transfer the much larger functions from Objective C to C.
Here is the C code I am trying:
int _stdcall game(int *games, int *gameskifte)
{
if (*games == 0){
if (*gameskifte == 1) return *games + 1;
else return *games + 2;}
else{
if (*games < 3){
if (*gameskifte == 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte == 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
Here is what the code is supposed to do:
If games = 0 and gameskifte = 1, return 1
if games = 0 (and by default gameskifte is not 1), return 2
If games < 3 and gameskifte = 1, return games + 2
If games < 3 (and by default gameshift is not 1), return games + 4
If games > 2 and gameskifte = 1, return games + 3
If games > 2 (and by default gameshift is not 1), return games + 5
What it does is ignore the value of gameshift and ALWAYS returns games + 4
I tried to change a few things...
This code (where all compares are "<" but the result should be the same)
int _stdcall game(int *games, int *gameskifte)
{
if (*games < 1){
if (*gameskifte < 2) return *games + 1;
else return *games + 2;}
else{
if (*games < 3){
if (*gameskifte < 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte < 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
Always gives me games + 1
And this (where all compares are ">" and where the result should NOT nessesary be the same as above):
int _stdcall game(int *games, int *gameskifte)
{
if (*games > 1){
if (*gameskifte > 2) return *games + 1;
else return *games + 2;}
else{
if (*games > 3){
if (*gameskifte > 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte > 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
always gives me games + 5
So when doing the return calculation it knows the value of *games but when comparing *games to another hardcoded value it throws a false when doing a direct or ">" compare and a positive when doing any "<" compare no matter if the value is lower or higher.
The rest of the project is
A def file: defFile.def:
LIBRARY ”minfil”
EXPORTS
game=game
The VBA:
Private Declare Function game Lib "c:\users\musholm\documents\visual studio 2013\Projects\mitprojekt\Debug\mitprojekt.dll" (ByRef games As Integer, ByRef gameskifte As Integer) As Integer
Function game1(games As Integer, gamesskifte As Integer) As Integer
game1 = game(games, gamesskifte)
End Function
The Excel function is =game1(x,y)
And finally the original objective c I am trying to recreate in C:
- (NSNumber *)game:(NSNumber *)games gamechange:(NSNumber *)gameskifte
{
int gamesab = [games intValue];
int gameskifteab = [gameskifte intValue];
int gamesud = 0;
if (gamesab == 0){
if (gameskifteab == 1) gamesud=1;
else gamesud=2;}
else{
if (gamesab<3){
if (gameskifteab==1)gamesud=gamesab+2;
else gamesud=gamesab+4;}
else{
if (gameskifteab==1)gamesud=gamesab+3;
else gamesud=gamesab+5;
}
}
return [NSNumber numberWithInt:gamesud];
}
VBA's Integer corresponds to C's short.
You want the function parameters and the return value As Long in VBA.
Also you are missing a * in else return games + 5;. Although you don't need * in the first place, you should remove them all and redeclare the function parameters in VBA with ByVal.
Related
My code is below :
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int* new = (int*)malloc(sizeof(int) * (nums1Size+nums2Size));
int i = 0;
int count1 = 0;
int count2 = 0;
if(nums1Size+nums2Size == 1){
if(nums1Size == 1)
return *nums1;
else
return *nums2;
}
else if(nums1Size == 0){
if((nums2Size & 0x1) == 0)
return (double)(nums2[nums2Size/2-1]+nums2[nums2Size/2])/2;
else
return (double)nums2[nums2Size/2];
}
else if(nums2Size == 0){
if((nums1Size & 0x1) == 0)
return (double)(nums1[nums1Size/2-1]+nums1[nums1Size/2])/2;
else
return (double)nums1[nums1Size/2];
}
while(i != (nums1Size+nums2Size))
{
if((nums1[count1 == nums1Size ? count1-1:count1] > nums2[count2 == nums2Size ? count2-1:count2]
&& (count2) != nums2Size)
|| (count1) == nums1Size)
{
*(new+i) = *(nums2+count2);
count2++;
}
else{
*(new+i) = *(nums1+count1);
count1++;
}
i++;
}
if(((nums1Size+nums2Size) & 0x1) == 0){
return (double)(new[(nums1Size+nums2Size)/2 - 1] + new[(nums1Size+nums2Size)/2]) / 2;
}
else
return (double)new[(nums1Size+nums2Size)/2];
}
And below is the submissions's runtime distribution on Leetcode :
The Question is, even if there are a lot of submitted codes with O(log (m+n)) in C but I think my code's Time complexity is O(m+n). so it doesn't make sense that my code is top 2% on Leetcode according to the distribution graph. of course linear is faster than log to a small amount of inputs but the test-cases are enough big to get beaten by O(log (m+n)). I don't know why my code get passed with that rate.
will greatly appreciate your comments!
From my top comment: You allocate new at the start of the function. If any of the "early escape" return statements are executed, you'll leak memory.
So do I have to put free() in every return statement? or how can i fix my code?
Don't do the malloc until after the top block of early escapes.
And, do the free at the bottom. To do this, you'll need an extra variable to hold the return value so you can safely do the free(new) (e.g. double retval;)
Side note: It's usually cleaner to replace (e.g.) *(new + i) with new[i]. Also, holding the code to <= 80 chars / line is also a good style.
Here's one way to fix your code [please pardon the gratuitous style cleanup]:
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new;
int i;
int count1 = 0;
int count2 = 0;
double retval;
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
return *nums1;
else
return *nums2;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
return (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
return nums2[nums2Size / 2];
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
return (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
return (double) nums1[nums1Size / 2];
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (i = 0; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
free(new);
return retval;
}
But, personally, I dislike multiple return statements in a function. It's harder to debug [using gdb] because you'd have to set a breakpoint on each return.
Here's a version that uses a do { ... } while (0); as a "once through" loop that allows us to eliminate the if/else "ladder" logic [which I also personally dislike] and have only a single return at the bottom. YMMV ...
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new = NULL;
int i = 0;
int count1 = 0;
int count2 = 0;
double retval;
do {
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
retval = *nums1;
else
retval = *nums2;
break;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
retval = (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
retval = nums2[nums2Size / 2];
break;
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
retval = (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
retval = (double) nums1[nums1Size / 2];
break;
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
} while (0);
if (new != NULL)
free(new);
return retval;
}
UPDATE:
thanks! I understood. your code is more clear than mine for real!. but what do you think about the performance between them? ( if/else and do{...}while(0)). because if we assume the compiler would work as we generally expect, if/else is faster than if if which is in do{...} in the revised code. thanks a lot again!
Actually, if we disassemble both versions [compiled with -O2], the do/while version is 4 assembly instructions shorter.
But, in order to tune it, you have to measure it.
The optimizer will pretty much make them similar.
The main bulk of the time of the function is spent in the for loop, which is the same for both. The speed of the loop dwarfs any extra overhead of do/while which might be an assembler instruction or two [but, again the do/while has fewer instructions].
So, tuning/optimizing the prolog/epilog code of the function isn't [usually] worth it. Speeding up the loop is.
To tune/optimize, either do profiling to determine where the code spends the most amount of time [or for something this simple, it's obviously the loop], or add timestamping and get elapsed time on the function [or various subparts].
As I mentioned, it's hard to add a breakpoint for a function that has multiple return statements.
Also, sometimes you can't attach a debugger. Or, it's difficult to find a meaningful place to put a breakpoint. For example, if you have a program that runs fine for (e.g.) days, and then aborts after (e.g.) 63 hours, you may need to do internal benchmarking and printf style debugging:
#ifdef DEBUG
#define dbgprint(_fmt) \
do { \
printf(_fmt); \
} while (0)
#else
#define dbgprint(_fmt) \
do { \
} while (0)
#endif
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
double retval;
dbgprint("findMedianSortedArrays: ENTER nums1Size=%d nums2Size=%d\n",
nums1Size,nums2Size);
// ... the code
dbgprint("findMediaSortedArrays: EXIT retval=%g\n",retval);
return retval;
}
It's much easier to insert the debug print statements with the second version.
BTW, I do this sort of thing all the time. And, one of my fortes is fast code and performance improvement [as I do a lot of realtime coding].
I'm trying to make a function calculating x to the power n (where x could be a double, n must be an int). A recursive algorithm would be this one, but implementing it in C gave me the stack-overflow error.
I tried finding my answer here, but the closest I found was this, which didn't satisfy my needs.
Here is my code:
double power_adapted(double x, int n) {
if (n == 0)
return 1;
else if (n == 1)
return x;
else if (n % 2 == 0)
return power_adapted(power_adapted(x, n / 2), 2);
else
return x * power_adapted(power_adapted(x, (n - 1) / 2), 2);
}
The recursive calls always pass 2 as n, so they will always trigger another recursive call.
I think you misinterpreted the formula. I would interpret it as:
else if (n % 2 == 0) {
double v = power_adapted(x, n / 2);
return v * v;
}
else {
double v = power_adapted(x, (n - 1) / 2);
return x * (v * v);
}
I don't think what you're trying to accomplish makes sense.
If you take a look at this part of code,
else if (n % 2 == 0)
return power_adapted(power_adapted(x, n / 2), 2);
else
return power_adapted(power_adapted(x, (n - 1) / 2), 2);
While the nested calls may present no problem (as a statement), the call on the outside always has n = 2 and the base cases depend on n.
Solving the problem:
By taking a look at the formula provided, I think you should have a base case for n == 2 to return x * x (this is the simplest change to the algorithm). So, the algorithm could be stated as follows:
double power_adapted(double x, int n) {
if (n == 0)
return 1;
else if (n == 1)
return x;
else if (n == 2)
return x * x;
else if (n % 2 == 0)
return power_adapted(power_adapted(x, n / 2), 2);
else
return x * power_adapted(power_adapted(x, (n - 1) / 2), 2);
}
I'm a first time programmer trying to complete a simple command line program as part of the first assignment for an online course I am taking, but I seem to have hit a roadblock that I can't figure out with GDB or my own research.
After hours of rewrites, and hours of debugging, I finally got the code below to compile. The program is supposed to take a credit card number as an input, and then check whether it's valid per the specifications of the assignment. I used a test number from here: PayPal Test Credit Cards
The odd thing is, when I enter an AMEX card number, it correctly produces the text "AMEX", but when I try a Visa or a Master Card, it prints "INVALID".
In GDB I broke at the Verify function and it seems to incorrectly skip these two if/else if statements without proceeding to the Checksum function even though conditions appear to be met.
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
...
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
...
The AMEX line of code that correctly executes is:
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
The arguments for all three lines seem to be formatted exactly the same. That is far as I could get in GDB though. I would print totalDigits, firstDigit, and secondDigit in GDB right before stepping through the above two non-executing lines and everything looked correct. So I'm stumped, why is the AMEX line executing, but not the others?
Thanks in advance everyone. This is the first program after hello.c that I've tried to write, so I am open to absolutely any criticism or suggestions if it looks like I'm doing something weird/wrong.
Full code:
checker.c
#include <stdio.h>
#include <stdlib.h>
int MAX = 16;
int* DigitSort(unsigned long long x, int* array);
int Verify(int* array);
int main (void)
{
int* output = malloc (sizeof(int) * (MAX + 2)); // creates a blank array for the individual digits of the card number.
unsigned long long userInput = 0;
do
{
printf("Please enter a credit card number:\n");
scanf("%lld", &userInput);
}
while (userInput <= 0); // checks to make sure the user entered a number.
switch(Verify(DigitSort(userInput, output))) // sorts the user's input into individual digits and verifies the card type and validity.
{
case 1 :
printf("VISA\n");
break;
case 2 :
printf("MASTERCARD\n");
break;
case 3 :
printf("AMEX\n");
break;
case 0 :
printf("INVALID\n");
break;
default :
printf("INVALID\n");
}
free(output);
return 0;
}
int Verify(int* array) // verifies whether or not a card number is valid. Must pass the function a sorted array of individual digits.
{
int* cardNumber = array;
int firstDigit = cardNumber[0];
int secondDigit = cardNumber[1];
int totalDigits = 0;
int Checksum(int* cardNumber, int totalDigits);
int i = 0;
while (firstDigit >= 1 && cardNumber[i] >= 0) // this step counts the number of digits in the array.
{
totalDigits = totalDigits + 1;
i++;
}
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
{
return 1;
}
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
{
return 2;
}
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
{
return 3;
}
else // if the card number doesn't match any of the above conditions or fails the checksum, an 'I' for Invalid is returned.
{
return 0;
}
}
int* DigitSort(unsigned long long x, int* array) // takes a long long as input and sorts it into individual digits
{
int* arrayReversed = malloc (sizeof(int) * (MAX + 2)); // creates a new array to hold the reversed order of digits.
int i = 0;
arrayReversed[0] = 0;
if (i < (MAX - 1) && x >= 10)
{
do
{
arrayReversed[i] = x % 10;
x = x / 10;
i++;
}
while (i < (MAX -1) && x >= 10);
}
if (i < MAX && x >= 1 && x <= 9)
{
arrayReversed[i] = (int) x;
x = (x - x);
}
if (x == 0)
{
int j = 0;
do
{
array[j] = arrayReversed[i]; // sorts the digits from the reversed array and places them into the sorted array.
j++;
i--;
}
while (j < MAX && i >= 0);
array[j] = -1;
}
free(arrayReversed);
return array;
}
int Checksum(int* cardNumber, int totalDigits)
{
int sum1 = 0;
int sum2 = 0;
int i = (totalDigits - 2);
int j = (totalDigits - 1);
while (i >= 0)
{
sum1 = ((cardNumber[i] * 2)%10) + ((cardNumber[i] * 2)/10) + sum1;
i -= 2;
}
while (j >= 0)
{
sum2 = (cardNumber[j] + sum2);
j -= 2;
}
if (((sum1 + sum2) % 10) == 0)
{
return 0;
}
else
{
return 1;
}
}
Your first problem is here:
if (firstDigit == 4 && totalDigits == (13 | 16) && ...
You need to write:
if (firstDigit == 4 && (totalDigits == 13 || totalDigits == 16) && ...
Your first check is looking for 0x1D == 29 as the number of digits (because, as paisanco points out in a comment, the | operator is the bitwise OR operator), and no credit card needs 29 digits (yet, and not for a long time to come). Note the extra parentheses for clarity and accuracy. Don't mess around risking removing them — the code won't work properly again. And in general, be explicit if your condition has both && and || operators and use parentheses to group terms explicitly.
You have similar problems elsewhere. As it happens, (4 | 7) is the same value as 7, so the condition works when the second digit is 7 (but not when it is 4). But it doesn't mean what you intended it to mean.
Computer languages don't work the same as human languages. Get used to writing out the condition somewhat more verbosely. Some other languages provide shorthands for these conditions; C is not such a language.
Function fun(n) is defined as such:
fun(n) = 1 (if n <=1)
fun(n) = fun(n/2) (if n is even)
fun(n) = 2*fun((n-1)/3) (if n> and n is odd)
I'm trying to write a recursive function to compute and return the result. I just started learning recursion, I got kind of lost while doing this function. Can someone correct me and explain to me? Thanks!
Here's what I did:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int fun(int n);
int main()
{
int num;
printf("\nEnter a number: ");
scanf("%d", num);
printf("Result = %d\n", fun(num));
return 0;
}
int fun(int n)
{
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
}
Expected output:
Enter a number: 13
Result = 2
Enter a number: 34
Result = 4
Output I'm getting instead:
Enter a number: 13
Result = 1
Enter a number: 34
Result = 1
scanf takes a pointer to int as argument for %d, i.e.,
scanf("%d", &num);
Also, your function fun does not handle all cases and may fall off the bottom:
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
The last else if condition is never met, because the previous check for n % 2 == 0 already returns in that case. Also the n > 1 is pointless because the first n <= 1 returns in all other cases.
You can simply make it:
else
{
return 2 * fun((n - 1) / 3);
}
The culprit is the last else if condition. Change it to:
else if ((n % 2) != 0)
The condition that n is odd is written wrong here. You wrote the same thing as for when n is even.
Its probably better to explicitly make the cases disjoint so you always return and there's no warning, like this:
int fun(int n)
{
if(n <= 1)
return 1;
if(n % 2 == 0)
return fun(n/2);
//No need for a condition, we know the last one must be satisfied
return 2 * fun((n-1)/3);
}
or, add another "default" case that indicates there was some error.
I think last if should be:
else if ((n > 1) && (n % 2 != 0))
Notice the != instead of ==.
The third condition
else if ((n > 1) && (n % 2 == 0))
is wrong, but instead of fixing it just you else no else if - because all other conditions were checked already.
I'm reading a book on C programming and try to do the exercises:
Write a program that prints a horizontal histogram consisting of stars(*). One star for every number there can be in the interval 0 ... 70.
#include <stdio.h>
void draw_stars(int number_of_stars) {
int counter = 0;
for(counter = 0; counter < number_of_stars; counter++) {
printf("*");
}
printf("\n");
}
int main(void) {
int counter1, counter2, ones, tens, zero, one, two, three, four, five, six, seven, eight, nine = 0;
for(tens = 0; tens < 7; tens++) {
if(tens == 0)
zero = zero + 1;
if(tens == 1)
one = one + 10;
if(tens == 2)
two = two + 10;
if(tens == 3)
three = three + 10;
if(tens == 4)
four = four + 10;
if(tens == 5)
five = five + 10;
if(tens == 6)
six = six + 10;
if(tens == 7)
seven = seven + 10;
for(ones = 0; ones < 9; ones++) {
if(ones == 0)
zero++;
if(ones == 1)
one++;
if(ones == 2)
two++;
if(ones == 3)
three++;
if(ones == 4)
four++;
if(ones == 5)
five++;
if(ones == 6)
six++;
if(ones == 7)
seven++;
if(ones == 8)
eight++;
if(ones == 9)
nine++;
}
}
draw_stars(zero);
draw_stars(one);
draw_stars(two);
draw_stars(three);
draw_stars(four);
draw_stars(five);
draw_stars(six);
draw_stars(seven);
draw_stars(eight);
draw_stars(nine);
}
For some reason my program enters a infinite loop printing stars. But I can't find out why?
I haven't been able to come up with any other solution, but I still think it's ugly and bloated. How would a real C programmer solve this?
Edit:
After reading and understanding the chapter about arrays in the book, I was able to write a more clean version of the program. I'm posting it here as it might help other beginners understand the use of arrays. Writing an identical program in terms of output, but using different functionality of the language is a great learning experience.
#include <stdio.h>
#define TENS 7
void draw_stars(int stars) {
int star_counter = 0;
for (star_counter = 0; star_counter < stars; star_counter++)
printf("%c", '*');
}
int main(void) {
int number_array[10];
int tens_counter, ones_counter;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter] = 0;
for (tens_counter = 0; tens_counter < TENS; tens_counter++) {
if (tens_counter != 0)
number_array[tens_counter] += 10;
else
number_array[tens_counter] += 1;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter]++;
}
for (ones_counter = 0; ones_counter < 10; ones_counter++) {
draw_stars(number_array[ones_counter]);
printf("\n");
}
}
Initialize all variables:
int counter1=0, counter2=0, ones=0, tens=0, zero=0, one=0..
BTW, for better performance,
replace if with else if except the first one in the block. Why do you want to check all if conditions when you already know only one is true?
FYI, when a condition is true in Else if, all other ifs are skipped.
If you wanted to initialize all ints to zero, you should write:
int counter1=0, counter2=0, ...
Now only nine is init by 0, other variables contain rubbish - arbitrary values.
in main() you have to initialize all variable with zero like
int counter1=0,counter2=0 and so on
otherwise it take garbage value and perform operation with those values and then output will be like
********
*****************
*****************
*****************
*****************
*****************
*****************
*******
*******