Cnix#

---
创建日期: 2012-11-03
---
这个是几段代码与分析,可能当时在看“Linux程序设计”,印象中也是后来整理的,开始分散在各自文本中。我当年还会些C呢!

程序空间 - 1#

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

void func(char* str) {
    char c1[] = "This always here.\n";
    char* c2  = "This always too.\n";
    char v1[100];
    strcpy(v1,str);
    printf("Add for const 1: %d\n",c1);
    printf("Add for const 2: %d\n",c2);
    printf("Add for var 1: %d\n",v1);
    printf("Add for arg : %d\n",str);
    printf("\n");
}

int main() {
    for (int i=0;i<2;i++) {
        func("Where am I");
    }
    printf("/*************/\n\n");
    for (int i=0;i<2;i++) {
        func("I am another");
    }
    return 0;
}

函数内的c1 c2 v1地址始终不变,arg则变化了,因为两个是预定义的字符串常量。

程序空间 - 2#

#include<stdio.h>

int* anoy() {
/*static int a;*/
    int a;
    a++;
    printf("I'm %d\n",a);
    return &a;
}

int main() {
    int* p;
    p = anoy();
    *p = 100;
    anoy();
    return 0;
}

可以通过指针访问函数中的变量呃,再次证明内存空间是预先定义好的。

struct & typedef#

#include<stdio.h>
#include<stdlib.h>

struct s1 {
    int x;
};
/* struct {
    int x;
    int y;
};*/
struct {
    int x;
    int y;
    int z;
} a;
struct s2 {
    int z;
} f;
typedef struct pp {
    int p;
} x;
typedef struct {
    int k;
} xx;

int main() {
    struct s1 st = {5};
    printf("This is from struct s1; %d\n",st.x);
    //a = {0,1,2};
    a.z = 0;
    printf("This is from anonymous struct; %d\n",a.z);
    (&f)->z = 4;
    printf("This is init s2; %d\n",f.z);
    struct s2 e = {2};
    printf("This is later s2; %d\n",e.z);
    x a = {3};
    xx d = {5};
    printf("This typedef pp->x; %d\n",a.p);
    printf("This typedef ??->xx; %d\n",d.k);
    return 0;
}

struct {} 及 struct x {} 是进行类型声明,后者可以再次访问而前者不能。如果单独struct后接变量名则进行定义。

typedef TYPE ALIAS 对某个类型重新声明,类型可以是前面两种结构的任意一种,因此也不能同时进行定义。

共享内存#

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>

int main() {
    int shmid;
    shmid = shmget((key_t)4234,sizeof(int),0666|IPC_CREAT);
    void* shm_mem = (void*)0;
    shm_mem = shmat(shmid,(void*)0,0);
    int* ptr;
    int valu;
    srand(getpid());
    ptr = (int*)shm_mem;
    valu = *ptr;
    printf("init: %d\n",valu);
    *ptr = rand();
    printf("afte: %d\n",*ptr);
    sleep(10);
    shmdt(shm_mem);
    sleep(10);
    shmctl(shmid,IPC_RMID,0);
    return 0;
}

记录在其它什么地方了吧,关于共享空间的回收问题。

接入到共享空间会计数+1,然后可以调用函数减少并删除,但是在减少到0之前不会删除。 而如果不调用删除,内容不会消去。 所以经常接入后立刻调用删除,而在真正需要的时候调用减去方式。

子进程#

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main() {
    pid_t p;
    int r;
    int t;
    t = time((time_t *) 0);
    srand(t);
    r = rand();
    printf("This is from the common part: %d\n",r);
    sleep(5);
    p = fork();
    if (p != 0) {
	printf("This is from parent: %d\n",r);
    } else {
	printf("This is from child: %d\n",r);
    }
    return 0;
}

共同部分并不会出现两次,所以子进程是从fork处继续进行,并非重新开始一个新的程序(这是我原来的误解)。 子进程的变量与父进程相同,所以子进程拷贝了所有的父进程状态。

外部调用#

//in file1.c
#include<stdio.h>
int func();
extern int i;
int main() {
    func();
    printf("%d\n",i);
    return 0;
}

//in file2.c
#include<stdio.h>
int i=99;
int func() {
    printf("This is %d.\n",i);
    return 1;
}

要使用外部内容得先声明,不过不能重复了,另外还有个static用法没有在此测试。