,
( -
). scanf(), .
- .
5.3. ,
.
5.4. , -
. -
strcmp().
5.5. , -
, ,
. , .
5.6. , -
: , , ; ; ; ,
; ; .
5.7. ?
struct man {
char name[20];
int salary;
} workers[] = {
{ "", 200 },
{ "", 180 },
{ "", 150 }
}, *wptr, chief = { "", 550 };
main(){
struct man *ptr, *cptr, save;
ptr = wptr = workers + 1;
cptr = &chief;
save = workers[2]; workers[2] = *wptr; *wptr = save;
wptr++; ptr--; ptr->salary = save.salary;
printf( "%c %s %s %s %s\n%d %d %d %d\n%d %d %c\n",
*workers[1].name, workers[2].name, cptr->name,
ptr[1].name, save.name,
wptr->salary, chief.salary,
(*ptr).salary, workers->salary,
wptr - ptr, wptr - workers, *ptr->name );
}
:
180 550 150 150
2 2
5.8. :
#include <stdio.h>
struct man{
. , 1992-95 - 177 - UNIX
char *name, town[4]; int salary;
int addr[2];
} men[] = {
{ "", "Msc", 100, { 12, 7 } },
{ "", "Len", 120, { 6, 51 } },
{ "", "Rig", 140, { 23, 84 } },
{ NULL, "" , -1, { -1, -1 } }
};
main(){
struct man *ptr, **ptrptr;
int i;
ptrptr = &ptr;
*ptrptr = &men[1]; /* men+1 */
printf( "%s %d %s %d %c\n",
ptr->name,
ptr->salary,
ptr->town,
ptr->addr[1],
ptr[1].town[2] );
(*ptrptr)++;
/* *ptr men[0] */
men[0].name = ptr->name; /* (char *) #1 */
strcpy( men[0].town, ptr->town ); /* char [] #2 */
men[0].salary = ptr->salary; /* int #3 */
for( i=0; i < 2; i++ )
men[0].addr[i] = ptr->addr[i]; /* #4 */
/* */
for(ptr=men; ptr->name; ptr++ )
printf( "%s %s %d\n",
ptr->name, ptr->town, ptr->addr[0]);
}
:
1) (ptrptr).
2) , (int, char,
long, ..., ) (.
#1 #3). () , -
( #4). ( )
strcpy ( #2).
, .
, : men[0]= *ptr;
3) printf() , -
.
4) (-
), NULL name -
.
5) town 3 ,
4 . , "Msc" 3, 4 -
: 'M','s','c','\0'.
.
() ( men ):
. , 1992-95 - 178 - UNIX
--ptr-- --ptrptr--
ptr | * |<------|---* |
---|--- ----------
|
/ =========men[0]==
/ men:|name | *---|-----> ""
| |---------------|
| |town |M|s|c|\0|
| |---------------|
| |salary| 100 |
| |---------------|
| |addr | 12 | 7 |
\ -----------------
\ =========men[1]==
\-->|name | *---|-----> ""
............
5.9. " ",
.
.
5.10. ( ) ,
.
, -
, .
?
int data[2];
data[0] = my_key;
data[1] = my_value;
write(fd, (char *) data, 2 * sizeof(int));
-, ( ,
3 2 3).
write(fd, (char *) data, sizeof data);
, data, &data? (:
). -, ,
?
struct _data {
int key;
int value;
} data;
data.key = my_key;
data.value = my_value;
write(fd, &data, sizeof data);
5.11. ? -
.
#include <stdio.h>
struct lnk{
char c;
. , 1992-95 - 179 - UNIX
struct lnk *prev, *next;
} chain[20], *head = chain;
add(c) char c;
{
head->c = c;
head->next = head+1;
head->next->prev = head;
head++;
}
main(){
char *s = "012345";
while( *s ) add( *s++ );
head->c = '-';
head->next = (struct lnk *)NULL;
chain->prev = chain->next;
while( head->prev ){
putchar( head->prev->c );
head = head->prev;
if( head->next )
head->next->prev = head->next->next;
}
}
5.12. , , -
. - '\n'. '+'.
. .
/ . :
struct elem{
char letter; /* */
char *word; /* */
struct elem *prev; /* */
struct elem *next; /* */
};
struct elem *head, /* */
*tail, /* */
*ptr, /* */
*prev; /* */
int c, cmp;
...
while((c = getchar()) != '\n' )
Insert(c, tail);
for(ptr=head; ptr != NULL; ptr=ptr->next)
printf(" %c\n", ptr->letter);
, calloc(),
malloc(), '\0' (0, NULL).
:
extern char *calloc();
/* c */
struct elem *NewElem(c) char c; {
struct elem *p = (struct elem *)
calloc(1, sizeof(struct elem));
/* calloc ,
* prev next
*/
p->letter = c; return p;
}
. , 1992-95 - 180 - UNIX
/* ptr ( - tail) */
Insert(c, ptr) char c; struct elem *ptr;
{ struct elem *newelem = NewElem(c), *right;
if(head == NULL){ /* */
head=tail=newelem; return; }
right = ptr->next; ptr->next = newelem;
newelem->prev = ptr; newelem->next = right;
if( right ) right->prev = newelem;
else tail = newelem;
}
/* ptr */
Delete( ptr ) struct elem *ptr; {
struct elem *left=ptr->prev, *right=ptr->next;
if( right ) right->prev = left;
if( left ) left->next = right;
if( tail == ptr ) tail = left;
if( head == ptr ) head = right;
free((char *) ptr);
}
.
struct elem *NewElem(char *s) {
struct elem *p = (struct elem *)
calloc(1, sizeof(struct elem));
p->word = strdup(s);
return p;
}
void DeleteElem(struct elem *ptr){
free(ptr->word);
free(ptr);
}
: .
strcmp(), :
struct elem *newelem;
if (head == NULL){ /* */
head = tail = NewElem(_);
return;
}
/* */
for(cmp= -1, ptr=head, prev=NULL;
ptr;
prev=ptr, ptr=ptr->next
)
if((cmp = strcmp(_, ptr->word)) <= 0 )
break;
cmp==0, . cmp < 0,
ptr ,
_, prev - (prev==NULL ,
); .. prev ptr. cmp > 0, -
( ptr==NULL).
head ==> "a" ==> "b" ==> "d" ==> NULL
| |
prev "c" ptr
. , 1992-95 - 181 - UNIX
if(cmp == 0) return; /* */
newelem = NewElem( _ );
if(prev == NULL){ /* */
newelem->next = head;
newelem->prev = NULL;
head->prev = newelem;
head = newelem;
} else if(ptr == NULL){ /* */
newelem->next = NULL;
newelem->prev = tail;
tail->next = newelem;
tail = newelem;
} else { /* prev ptr */
newelem->next = ptr;
newelem->prev = prev;
prev->next = newelem;
ptr ->prev = newelem;
}
5.13.
struct complex {
double re, im;
};
, :
struct complex add( c1, c2 )
struct complex c1, c2;
{
struct complex sum;
sum.re = c1.re + c2.re;
sum.im = c1.im + c2.im;
return sum;
}
struct complex a = { 12.0, 14.0 },
b = { 13.0, 2.0 };
main(){
struct complex c;
c = add( a, b );
printf( "(%g,%g)\n", c.re, c.im );
}
5.14. , - .
: -
typedef struct {
int ai[5];
} intarray5;
intarray5 a, b = { 1, 2, 3, 4, 5 };
a = b;
:
. , 1992-95 - 182 - UNIX
a.ai[2] = 14;
for(i=0; i < 5; i++) printf( "%d\n", a.ai[i] );
.
:
typedef int ARR16[16];
ARR16 d;
void f(ARR16 a){
printf( "%d %d\n", a[3], a[15]);
a[3] = 2345;
}
void main(void){
d[3] = 9; d[15] = 98;
f(d);
printf("Now it is %d\n", d[3]);
}
printf "Now it is 2345", f -
, ; a[3]=2345 .
, , -
, (
, ).
5.15. - ,
- .
:_.
( ).
struct XYZ {
/* unsigned */
unsigned x:2; /* 0 .. 2**2 - 1 */
unsigned y:5; /* 0 .. 2**5 - 1 */
unsigned z:1; /* YES=1 NO=0 */
} xyz;
main(){
printf("%u\n", sizeof(xyz)); /* == sizeof(int) */
xyz.z = 1; xyz.y = 21; xyz.x = 3;
printf("%u %u %u\n", xyz.x, ++xyz.y, xyz.z);
/*
* 2**_ - 1
*/
xyz.y = 32 /* */ + 7; xyz.x = 16+2; xyz.z = 11;
printf("%u %u %u\n", xyz.x, xyz.y, xyz.z); /* 2 7 1 */
}
1 :
#define FLAG1 01
#define FLAG2 02
#define FLAG3 04
int x; /* */
x |= FLAG1; x &= ~FLAG2; if(x & FLAG3) ...;
struct flags {
unsigned flag1:1, flag2:1, flag3:1;
} x;
x.flag1 = 1; x.flag2 = 0; if( x.flag3 ) ...;
. , 1992-95 - 183 - UNIX
,
(.. ).
"&",
!
5.16. . -
. :
, !
#include <stdio.h>
#define SZ 5
extern char *malloc();
#define VARTYPE char
struct obj {
struct header { /* */
int cls;
int size; /* */
} hdr;
VARTYPE body [1]; /* :
*/
} *items [SZ]; /* */
#define OFFSET(field, ptr) ((char *) &ptr->field - (char *)ptr)
int body_offset;
/* */
struct obj *newObj( int cl, char *s )
{
char *ptr; struct obj *op;
int n = strlen(s); /* ( VARTYPE) */
int newsize = sizeof(struct header) + n * sizeof(VARTYPE);
printf("[n=%d newsize=%d]\n", n, newsize);
/* newsize = (sizeof(struct obj) - sizeof(op->body)) + n * sizeof(op->body);
, struct(obj)
sizeof(int).
,
op->body.
newsize = body_offset + n * sizeof(op->body);
*/
/* */
ptr = (char *) malloc(newsize);
/* */
op = (struct obj *) ptr;
op->hdr.cls = cl;
op->hdr.size = n;
strncpy(op->body, s, n);
return op;
}
. , 1992-95 - 184 - UNIX
void printobj( struct obj *p )
{
register i;
printf( "OBJECT(cls=%d,size=%d)\n", p->hdr.cls, p->hdr.size);
for(i=0; i < p->hdr.size; i++ )
putchar( p->body[i] );
putchar( '\n' );
}
char *strs[] = { "a tree", "a maple", "an oak", "the birch", "the fir" };
int main(int ac, char *av[]){
int i;
printf("sizeof(struct header)=%d sizeof(struct obj)=%d\n",
sizeof(struct header), sizeof(struct obj));
{
struct obj *sample;
printf("offset(cls)=%d\n", OFFSET(hdr.cls, sample));
printf("offset(size)=%d\n", OFFSET(hdr.size, sample));
printf("offset(body)=%d\n", body_offset = OFFSET(body, sample));
}
for( i=0; i < SZ; i++ )
items[i] = newObj( i, strs[i] );
for( i=0; i < SZ; i++ ){
printobj( items[i] ); free( items[i] ); items[i] = NULL;
}
return 0;
}
5.17. , "". ,
, .
.
UNIX : ,
( ).
/* , ,
* .. "" - , "" - .
* !
* .
*/
#include <stdio.h>
extern char *malloc(), *gets();
#define MAX 3 /* */
int nelems = 0; /* */
struct elem { /* */
char *key; /* - - */
struct elem *next; /* */
/* ... - ... */
} *head; /* */
void printList(), addList(char *), forget();
. , 1992-95 - 185 - UNIX
void main(){ /* a b c d b a c */
char buf[128];
while(gets(buf)) addList(buf), printList();
}
/* */
void printList(){ register struct elem *ptr;
printf( " %d \n", nelems );
for(ptr = head; ptr != NULL; ptr = ptr->next )
printf( "\t\"%s\"\n", ptr->key );
}
/* */
void addList(char *s)
{ register struct elem *p, *new;
/* - */
for(p = head; p != NULL; p = p->next )
if( !strcmp(s, p->key)){ /* . */
if( head == p ) return; /* */
/* */
new = p; /* */
for(p = head; p->next != new; p = p->next );
/* p new */
p->next = new->next; goto Insert;
}
/* */
if( nelems >= MAX ) forget(); /* */
if((new = (struct elem *) malloc(sizeof(struct elem)))==NULL) goto bad;
if((new->key = malloc(strlen(s) + 1)) == NULL) goto bad;
strcpy(new->key, s); nelems++;
Insert: new->next = head; head = new; return;
bad: printf( " \n" ); exit(13);
}
/* */
void forget(){ struct elem *prev = head, *tail;
if( head == NULL ) return; /* */
/* ? */
if((tail = head->next) == NULL){ tail=head; head=NULL; goto Del; }
for( ; tail->next != NULL; prev = tail, tail = tail->next );
prev->next = NULL;
Del: free(tail->key); free(tail); nelems--;
}
. , 1992-95 - 186 - UNIX
* 6. UNIX. *
.
.
- .
UNIX - (). , -
.
- , ,
... -
( ). ,
, . , ""
(.. ) , -
. "" ,
"" , " " , -
(, , !).
"" (swapping).
,
; ( )
. , , , -
- ( ), -
/bin/csh ( /bin/sh).
"", ""
:
a) main:
void main(int argc, char *argv[], char *envp[]);
$ a.out a1 a2 a3
main a.out
argc = 4 /* */
argv[0] = "a.out" argv[1] = "a1"
argv[2] = "a2" argv[3] = "a3"
argv[4] = NULL
argv[0]
|-.
b) "" ( "") char *envp[],
extern char **environ;
"="
NULL ( argv). -
char *getenv( char * );
, NULL .
c) . () 3 :
FILE * stdin stdout stderr
fd 0 1 2
____________________
|- ps -ef
#include <stdio.h>
main(ac, av) char **av; {
execl("/bin/sleep", "Take it easy", "1000", NULL);
}
. , 1992-95 - 187 - UNIX
" "
, . , -
( open, creat, pipe, fopen).
20 (
), (, 64). MS DOS 2
: stdaux -
, stdprn - .
d) ,
int pid = getpid();
""
int ppid = getppid();
:
kill(pid /* */, sig /* */);
signal (sig /* */, f /* f(sig)*/);
e) : , ,
, .
f) () : ,
, -"",
chdir(char *__);
(
MS DOS, ). "" -
: ; (pgrp);
() (uid), (gid),
, ; ...
g) ( ) ("")
"" .
h)
(""). , -
, (-
shared memory);
( ).
,
""-, ""- ( );
"", - ( -
) ( ).
" ". ?
- - . , -
.
.
- . -
, (..
) , |-.
____________________
|- , -
, , ,
.
, ( ,
), - ! ,
: UNIX-
. - "
", , .. ,
. , , -
, :
, (
- -
). , , , -
, include-
. .
. , 1992-95 - 188 - UNIX
" " " -
", .. . ,
|=,
,
( MS DOS, ,
). 2 : -
-"", -
. - -
- - .
:
1. ;
2. , , u-area
(context switching);
3. ;
4. , ( , -
);
5. ;
6. ;
7. - - ;
8. ;
9. ;
10. .
( 7) "",
(, ). -
. "" ( ) -
.
: 0 - , (-1) - ;
( open(), (-1) -
. errno
, ( ,
include- <errno.h> E). ,
,
, :
#include <errno.h> /* */
extern int errno;
extern char *sys_errlist[];
int value;
if((value = sys_call(...)) < 0 ){
printf("Error:%s(%d)\n", sys_errlist[errno],
errno );
exit(errno); /* */
}
____________________
, -
. , UNIX , -
fork, exec, wait -
!
-
(, , -
, ). -
( - ,
),
, , .
|= , (
), ...
. , 1992-95 - 189 - UNIX
sys_errlist, ,
- (-). per-
ror().
6.1. .
6.1.1. stat, , :
, , , FIFO-. :
#include <sys/types.h>
#include <sys/stat.h>
typeOf( name ) char *name;
{ int type; struct stat st;
if( stat( name, &st ) < 0 ){
printf( "%s \n", name );
return 0;
}
printf(" %d \n", st.st_nlink);
switch(type = (st.st_mode & S_IFMT)){
case S_IFREG:
printf( " %ld \n",
st.st_size ); break;
case S_IFDIR:
printf( "\n" ); break;
case S_IFCHR: /* */
case S_IFBLK: /* */
printf( "\n" ); break;
case S_IFIFO:
printf( "FIFO-\n" ); break;
default:
printf( " \n" ); break;
} return type;
}
6.1.2. , : , , -
.
struct stat st; int used, fd;
for(fd=0; fd < NOFILE; fd++ ){
used = fstat(fd, &st) < 0 ? 0 : 1;
...
}
0..NOFILE-1 (
0..19). fstat - fd (<0), ,
(.. ). NOFILE
include- <sys/param.h>, .
6.1.3. ls,
( ".") .
, . "." ".." .
header- <sys/dir.h> "" -
: - , direct,
, :
. , 1992-95 - 190 - UNIX
struct direct {
unsigned short d_ino; /* 2 : I- */
char d_name[DIRSIZ]; /* */
};
BSD - , -
, 1 256 .
, '\0',
'/', . ,
( !), ( MS DOS,
, ()),
(.. ) ! 14 (DIRSIZ)
, '\0'.
:
1. putchar()- . -
DIRSIZ, '\0'.
2. d_name :
char buf[ DIRSIZ + 1 ];
strncpy(buf, d.d_name, DIRSIZ);
buf[ DIRSIZ ] = '\0';
, ,
, .
3. printf():
#include <sys/types.h>
#include <sys/dir.h>
struct direct d;
...
printf( "%*.*s\n", DIRSIZ, DIRSIZ, d.d_name );
, d_ino 0 (
I- 1, 0).
() , I- , -
, : d_ino=0; -
! d_ino==0 -
.
(creat, link, mknod)
( ) d_ino==0, -
( -
). - .
: "." -
( I-node), ".." - .
"/" (.. d_ino==2).
. ""
...
UNIX - . -
. ( |=) - -
write. ,
creat, unlink, link, mkdir, rmdir, rename, mknod.
:
w
S_IWRITE.
____________________
|= (superuser) uid==0. "" -
, . ,
...
. , 1992-95 - 191 - UNIX
. : ,
. ,
-
, !
r
S_IREAD. ( opendir, .
): ,
.