R
rir3760
Since a few days ago I have been working with the program I post
below (a school assignment). The purpose of the program is to work
with the va_ macros (stdarg.h) and arrays of arrays, hopefully
learning a little bit in the process.
The objective of the fn_memset function is to set all the chars in
the arrays passed (of type array N of array M of char) to a
specific char, somewhat similar to what the standard function
memset does:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#define N_MAT 10
#define T_NOM 40
#define T_NIF 10
#define T_POB 15
char alu_nom[N_MAT][T_NOM];
char alu_nif[N_MAT][T_NIF];
char alu_pob[N_MAT][T_POB];
void fn_memset(char car, int n_args, ...);
int main(void)
{
int i;
fn_memset('A', 6, T_NOM, alu_nom, T_NIF, alu_nif,
T_POB, alu_pob);
for (i = 0; i < N_MAT; i++){
alu_nom[T_NOM - 1] = '\0';
alu_nif[T_NIF - 1] = '\0';
alu_pob[T_POB - 1] = '\0';
}
puts("Array alu_nom[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_nom);
printf("\n");
puts("Array alu_nif[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_nif);
printf("\n");
puts("Array alu_pob[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_pob);
printf("\n");
return EXIT_SUCCESS;
}
void fn_memset(char car, int n_args, ...)
{
int i, j, tam;
char *aux;
va_list pa;
va_start(pa, n_args);
while(n_args > 0){
tam = va_arg(pa, int);
aux = va_arg(pa, char *);
for (i = 0; i < N_MAT; i++)
for (j = 0; j < tam; j++)
*(aux + i * tam + j) = car;
n_args -= 2;
}
va_end(pa);
}
The compiler (and splint) didn't emit any errors, and the program
produced the expected output with no run-time errors but I think I
just got 'lucky behaviour'.
This because I discovered (with horror ;-) that the operation of
'flattening an array' is illegal as the pointer to char moves from
one array M of char to another one, or at least that's what I
found in the book 'Pointers on C' by Kenneth A. Reek.
As I'm still a beginner in C without a copy of the standard I
don't want to fall into the scenario "OK let's try such and such
and if it works in my system then ...". Instead what better than
asking the pros of comp.lang.c a few questions? ;-)
First, can the function fn_memset be implemented with standard C?
Second, can a cast consist of values that are calculated at run-
time? For example:
void fn_memset(void *a, size_t n, size_t m)
{
size_t i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
((char (*)[m]) a)[j] = 'x';
}
Third (and related), can a pointer declaration consist of values
that are calculated at run-time? In a similar vein:
void fn_memset(void *a, size_t n, size_t m)
{
size_t i, j;
char (*foo)[m] = a;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
foo[j] = 'x';
}
Last question, as you can see I have many holes in my knowledge of
C so please can someone point me to didactic material (preferably
online) about the correct use of declarations, casting and
typedef's?
Thanks for your time.
below (a school assignment). The purpose of the program is to work
with the va_ macros (stdarg.h) and arrays of arrays, hopefully
learning a little bit in the process.
The objective of the fn_memset function is to set all the chars in
the arrays passed (of type array N of array M of char) to a
specific char, somewhat similar to what the standard function
memset does:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#define N_MAT 10
#define T_NOM 40
#define T_NIF 10
#define T_POB 15
char alu_nom[N_MAT][T_NOM];
char alu_nif[N_MAT][T_NIF];
char alu_pob[N_MAT][T_POB];
void fn_memset(char car, int n_args, ...);
int main(void)
{
int i;
fn_memset('A', 6, T_NOM, alu_nom, T_NIF, alu_nif,
T_POB, alu_pob);
for (i = 0; i < N_MAT; i++){
alu_nom[T_NOM - 1] = '\0';
alu_nif[T_NIF - 1] = '\0';
alu_pob[T_POB - 1] = '\0';
}
puts("Array alu_nom[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_nom);
printf("\n");
puts("Array alu_nif[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_nif);
printf("\n");
puts("Array alu_pob[][]:");
for (i = 0; i < N_MAT; i++)
printf("%s\n", alu_pob);
printf("\n");
return EXIT_SUCCESS;
}
void fn_memset(char car, int n_args, ...)
{
int i, j, tam;
char *aux;
va_list pa;
va_start(pa, n_args);
while(n_args > 0){
tam = va_arg(pa, int);
aux = va_arg(pa, char *);
for (i = 0; i < N_MAT; i++)
for (j = 0; j < tam; j++)
*(aux + i * tam + j) = car;
n_args -= 2;
}
va_end(pa);
}
The compiler (and splint) didn't emit any errors, and the program
produced the expected output with no run-time errors but I think I
just got 'lucky behaviour'.
This because I discovered (with horror ;-) that the operation of
'flattening an array' is illegal as the pointer to char moves from
one array M of char to another one, or at least that's what I
found in the book 'Pointers on C' by Kenneth A. Reek.
As I'm still a beginner in C without a copy of the standard I
don't want to fall into the scenario "OK let's try such and such
and if it works in my system then ...". Instead what better than
asking the pros of comp.lang.c a few questions? ;-)
First, can the function fn_memset be implemented with standard C?
Second, can a cast consist of values that are calculated at run-
time? For example:
void fn_memset(void *a, size_t n, size_t m)
{
size_t i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
((char (*)[m]) a)[j] = 'x';
}
Third (and related), can a pointer declaration consist of values
that are calculated at run-time? In a similar vein:
void fn_memset(void *a, size_t n, size_t m)
{
size_t i, j;
char (*foo)[m] = a;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
foo[j] = 'x';
}
Last question, as you can see I have many holes in my knowledge of
C so please can someone point me to didactic material (preferably
online) about the correct use of declarations, casting and
typedef's?
Thanks for your time.