Linux-C起步

名称解释

  1. ANSI C
    C语言标准,为各种操作系统上的C程序提供可移植性的保证
  2. POSIX标准
    定义了兼容操作系统的C语言系统接口以及工具标准
  3. 库函数
    库函数完成常见的特定功能,被应用程序调用
  4. 系统调用
    系统调用函数与操作系统相关,不同的操作系统使用的系统调用可能不同。库函数中也可以使用系统调用

第一个程序

写一个程序first.c

#include <stdio.h>

int main(int argc,char **argv)
{
  printf("this is first proram.\n");
  return 0;
}

使用gcc进行编译,链接

$ gcc first.c

运行一下看结果

$ ./a.out

调用函数

写一个阶乘的函数factorial.c

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

int factorial(int n)
{
  if(n <= 1) return 1;
  else
    return factorial (n-1) * n;
}

写一个调用文件second.c

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

int factorial(int n);

int main(int argc, char **argv)
{
  int n;
  if(argc < 2){
    printf("Usage: %s \n", argv[0]);
    return -1;
  }else{
    n = atoi(argv[1]);
    printf("Factorial of %d is %d . \n",n,factorial(n));
    return 0;
  }
}

编译和调用方法

$ gcc -c factorial.c
$ gcc -c second.c
$ gcc -o second factorial.o second.o
$ ./second  6

Make工具的使用

刚才我们看到了,如果我们的程序有多个文件,我们需要编译,链接才能正常调用程序。这个过程是很繁琐的,我们可以使用make工具来解决这个问题。
make工具会调用makefile文件,我们先写一个makefile看看
Makefile

second : second.o factorial.o
        gcc -o second second.o factorial.o
second.o : second.c
        gcc -c second.c
factorial.o : factorial.c
        gcc -c factorial.c
clean :
        rm -f *.o
        rm -f second

如果发现make有如下错误:

Makefile:2: *** 遗漏分隔符 。 停止。

可能是执行文件开头使用了空格,应该使用TAB。

Makefile中的常用变量
$@--目标文件
$^--所有依赖的文件
@<--第一个依赖文件

main: main.o mytool1.o mytool2.o
        cc -o $@ $^
main.o: main.c mytool1.h mytool2.h
        cc -c $<
mytool1.o: mytool1.c mytool1.h
        cc -c $<
mytool2.o: mytool2.c mytool2.h
        cc -c $<

库文件的使用

上面的例子中我们使用了printf函数,这个函数的实现是在库文件中。我们连接自己的应用程序的时候,编译器会查找对应函数的连接位置,运行时在当前系统内存空间中查找该库函数在对应库文件中的位置。
Linux系统下有两种库文件:

  1. 静态库:.a为后缀,应用程序从静态库中复制函数到二进制文件中
  2. 共享库:.so为后缀,应用程序运行时将函数代码从共享库文件中读出,从而间接引用。

系统库的路径:

# 系统必备共享库
/lib
# 标准共享库和静态库
/usr/lib
# 本地函数库
/usr/local/lib

库文件的搜索路径为:

  1. 环境变量:LD_LIBRARY_PATH 所指定的位置
  2. 搜索动态加载器在/etc 目录下的缓存文件 /etc/ld.so.cache

在进行cc编译的时候,会自动链接一些常用的库,这就是为什么printf不需要指定链接库的原因。如果我们需要指定库的路径可以使用如下方法:

cc -o temp temp.c -L/home/hutou/myLib

系统缺省库位置:/lib,/usr/lib,/usr/local/lib

静态库的使用

  1. 创建静态库:主要使用ar命令
    创建hello.c,hello.h 文件
#ifndef _libhello_H_
#define _libhello_H_
void hello(void);

#endif
#include <stdio.h>
#include "hello.h"

void hello(void){
        printf("this is a static lib.\n");
}

编译生成静态库hello.a

$ gcc -c hello.c
$ ar rc hello.a hello.o
  1. 使用静态库
    使用静态库需要两个文件:头文件,静态库文件
    默认库文件如果不在库搜索路径中,需要将此库文件拷贝到当前目录,或者在编译时指定库文件路径
    书写一个调用静态库的文件 libuse.c
#include <stdio.h>
#include "hello.h"

int main(int argc, char **argv){
        hello();
        return 0;
}

编译链接

$ gcc -o useHello libuse.c hello.a 

共享库的使用

共享库的创建基本上与静态库相同,主要的差别体现在编译上

  1. 使用gcc和参数-fPIC将源代码编译成.o的目标代码
  2. 使用-shared来创建共享库

下面我们使用上面的hello.c,编译成共享库

# 生成.o的目标文件
gcc -fPIC -c hello.c
# 编译共享库,指定共享库名称和版本,-lc表示引用c库
 gcc -shared  -o libhello.so.1.0 hello.o -lc
# 创建软连接
ln -sf libhello.so.1.0 libhello.so

下面我们看看怎么使用共享库

# 编译程序,生成目标文件
gcc -c libuse.c -o libuse.o
# 连接程序,-L 表示查找库的路径
gcc -o useDynHello libuse.o -L ./ -lhello
# 通过ldd命令查看引用的动态库
ldd useDynHello
# 调用程序,需要指定共享库的位置
LD_LIBRARY_PATH=$(pwd) ./useDynHello

说明一下,还记得我们说过的库文件的搜索路径。我们在链接程序的时候,指定了 -L 的路径,如果将我们的共享库放置在可以搜索到的路径下,则不用指定此参数。

进程

程序:包含可执行代码的文件,是一个静态文件。
进程:一个开始执行但是还没有结束的程序实例。
程序被系统调入内存,系统给程序分配一定的资源,让程序变成进程,为了区分进程,系统会给每一个进程分配一个ID号。进程有新建,运行,阻塞,就绪,完成五个状态。

  1. 获得进程ID号
#include <unist.h>
pid_t getpid(void);  //  获得进程的ID
pid_t getppid(void);  //  获得父进程的ID

演示用程序

#include <unistd.h>
#include <stdio.h>
int main(int argc,char *argv){
        printf("process id = %d\n",getpid());
        printf("process parent id = %d\n", getppid());
}
  1. 运行中出现:段错误(吐核)
    使用如下的命令进行调试(pid是运行的程序)
strace ./pid
  1. 进程的所有者和执行者
#include <stdio.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
    printf("这是程序的运行者%d\n", getuid());
    printf("这是程序的所有者%d\n", geteuid());
    printf("这是组ID =%s\n", getgid());
    printf("这是组EID =%s\n", getegid());
    return 0;
}
  1. 登录用信息
#include <stdio.h>
#include <pwd.h>
int main(int argc, char const *argv[])
{
        struct passwd* my_info;
        my_info = getpwuid(getuid());

        if(my_info)
        {
                printf("我的登录名:%s\n", my_info->pw_name);
                printf("我的密码:%s\n", my_info->pw_passwd);
                printf("我的ID= %ld\n", my_info->pw_uid);
                printf("我的组ID= %ld\n", my_info->pw_gid );
                printf("我的真实名称:%s\n", my_info->pw_gecos);
                printf("我的Home目录:%s\n", my_info->pw_dir);
                printf("我的Sheel:%s\n", my_info->pw_shell);
        }
        return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容