2016-17 Programmi C
Jump to navigation
Jump to search
C language - No Libraries
The following programs do not use library functions (only printf, just to have a feedback of the results).
arrays, pointers and structs
#include <stdio.h>
char *spoint="hello";
char sarr[]="hello";
struct strs {
char s[6];
} sstruct = {"hello"};
void foo(char *s) {
s[4]=0;
}
void bar(struct strs s) {
s.s[4]=0;
printf("from bar %s\n", s.s);
}
int main(int argc, char *argv[]) {
printf("%s %s %s\n", spoint, sarr, sstruct.s);
foo(sarr);
printf("%s %s %s\n", spoint, sarr, sstruct.s);
bar(sstruct);
printf("%s %s %s\n", spoint, sarr, sstruct.s);
// test the following statements, one at a time
//spoint = sarr;
//sarr = spoint;
foo(spoint);
printf("%s %s %s\n", spoint, sarr, sstruct.s);
}
iteration and recursion
#include <stdio.h>
struct elem {
int val;
struct elem *next;
};
struct elem *head = NULL;
struct elem *rinsert(struct elem *new, struct elem *head) {
if (head == NULL || new->val < head->val) {
new->next = head;
return new;
} else {
head->next = rinsert(new, head->next);
return head;
}
}
struct elem *iinsert(struct elem *new, struct elem *head) {
struct elem **pnext;
for (pnext = &head;
*pnext != NULL && new->val > (*pnext)->val;
pnext = &((*pnext)->next))
;
new->next = *pnext;
*pnext = new;
return head;
}
void rprint(struct elem *this) {
if (this) {
printf("%d ",this->val);
rprint(this->next);
}
}
void iprint(struct elem *this) {
for ( ; this != NULL; this = this->next)
printf("%d ",this->val);
}
struct elem test[]={{5},{3},{9},{1},{7}};
#define NELEM (sizeof(test) / sizeof(struct elem))
int main(int argc, char *argv[]) {
int i;
for (i = 0; i < NELEM; i++)
head = rinsert(&test[i], head);
rprint(head);
printf("\n");
iprint(head);
printf("\n");
head = NULL;
for (i = 0; i < NELEM; i++)
head = iinsert(&test[i], head);
rprint(head);
printf("\n");
iprint(head);
printf("\n");
}
comma operator
#include <stdio.h>
int slen(char *s) { /* in real programs use strlen instead */
size_t rval;
for (rval = 0; *s != 0; s++, rval++)
;
return rval;
}
int ispal(char *s) {
int i,j;
for (i=0, j=slen(s)-1; i < j; i++, j--) {
if (s[i] != s[j])
return 0;
}
return 1;
}
void reverse(char *s) {
int i,j;
for (i=0, j=slen(s)-1; i < j; i++, j--)
s[j] ^= s[i] ^= s[j] ^= s[i];
}
int main(int argc, char *argv[1]) {
for ( ;argc > 1; argv++, argc--) {
printf("\"%s\" is%s palindrome\n", argv[1],
ispal(argv[1])?"":"n't");
reverse(argv[1]);
printf("\"%s\"\n", argv[1]);
}
}
string by value
#include <stdio.h>
int slen(char *s) { /* in real programs use strlen instead */
int rval;
for (rval = 0; *s != 0; s++, rval++)
;
return rval;
}
void printxvowel(char v, char *s) {
int s_len = slen(s);
char locals[s_len];
int i;
for (i=0; i<s_len; i++) {
switch (s[i]) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
locals[i] = v;
break;
default:
locals[i] = s[i];
break;
}
}
printf("-> %s\n<- %s\n",s,locals);
}
int main(int argc, char *argv[]) {
for ( ; argc > 1; argc--, argv++) {
printxvowel('a',argv[1]);
printxvowel('e',argv[1]);
printxvowel('i',argv[1]);
printxvowel('o',argv[1]);
printxvowel('u',argv[1]);
}
return 0;
}
test it using "Garibaldi fu ferito, fu ferito ad una gamba, Garibaldi che comanda, che comanda il battaglion" as argv[1].
tables and preprocessor tricks
#include <stdio.h>
#define rows_of(X) (sizeof(X) / sizeof((X)[0]))
#define printTable(X) do { \
int i; \
printf("TABLE " #X ": size of element %d\n" \
"(printed by the line %d of source file %s)\n", \
sizeof(*(table ## X)), __LINE__, __FILE__); \
for (i = 0; i < rows_of(table ## X); i++) \
printf(#X " %02d %s\n",i,table ## X [i]); \
} while (0);
char tableA[][50] = {"Sempre caro mi fu quest'ermo colle,",
"e questa siepe, che da tanta parte",
"dell’ultimo orizzonte il guardo esclude."};
char *tableB[] = {"Sempre caro mi fu quest'ermo colle,",
"e questa siepe, che da tanta parte",
"dell’ultimo orizzonte il guardo esclude."};
int main(int argc, char *argv[1]) {
int i;
printTable(A);
printf("\n");
printTable(B);
}
arrays and pointers
#include <stdio.h>
int slen(char *s) { /* in real programs use strlen instead */
size_t rval;
for (rval = 0; *s != 0; s++, rval++)
;
return rval;
}
void echoargs(int argc, char *argv[]) {
int i;
for (i = 0; i < argc; i++)
printf("argv[%d] = \"%s\"\n",i,argv[i]);
printf("\n");
}
enum state {SPACE, CHAR};
int splitargv(char *s, char **argv) {
enum state state = SPACE;
int count = 0;
for (; *s != 0; s++) {
if (*s == ' ' || *s == '\t' || *s == '\n') {
if (state != SPACE)
count++;
if (argv != NULL)
*s = 0;
state = SPACE;
} else {
if (state == SPACE && argv != NULL)
*argv++ = s;
state = CHAR;
}
};
if (state != SPACE)
count++;
if (argv != NULL)
*argv = NULL;
return count;
}
void splitargs(char *args) {
int newargc = splitargv(args, NULL);
char *newargv[newargc + 1];
splitargv(args, newargv);
echoargs(newargc, newargv);
}
int main(int argc, char *argv[1]) {
echoargs(argc, argv);
for ( ; *argv != NULL; argv++) {
printf("Split \"%s\"\n",*argv);
splitargs(*argv);
}
}
This is a simplified version of the idea used in the libexecs library. Test this program using args like:
./a.out "ciao mare" "a b c"
void * and function pointers
#include <stdio.h>
typedef void (*voidfun) (void *arg);
void printint(void *arg) {
int *iarg = arg;
printf("int %d\n", *iarg);
}
void printstring(void *arg) {
char *sarg = arg;
printf("int %s\n", sarg);
}
void printpointer(void *arg) {
printf("pointer %p\n", arg);
}
void printfun(void *arg) {
voidfun fun = arg;
fun((void *) 0x42);
}
void launch(voidfun f, void *opaque) {
f(opaque);
}
int main(int argc, char *argv[1]) {
int v = 235;
char *s = "Lasciate ogni speranza, o voi ch'entrate";
launch(printint, &v);
launch(printstring, s);
launch(printfun, printpointer);
return 0;
}
This technique is used to implement callbacks with opaque args.