鱼C论坛

 找回密码
 立即注册
查看: 1776|回复: 15

[已解决]如何把若干个函数单独放在一个文件里

[复制链接]
发表于 2022-5-19 15:18:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以前的写法,就随便放在某个文件里,命名XX.C   然后在主文件里  include  <xx.c>    但是被告知 这是不规范用法
最佳答案
2022-5-19 15:37:42
本帖最后由 hrpzcf 于 2022-5-19 15:39 编辑

函数单独放.c文件,新建一个.h文件,定义所有函数原型,主xx.c文件内include .h文件,编译的时候指定所有.c文件,比如 gcc xx.c a.c b.c d.c -o main
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-5-19 15:37:42 | 显示全部楼层    本楼为最佳答案   
本帖最后由 hrpzcf 于 2022-5-19 15:39 编辑

函数单独放.c文件,新建一个.h文件,定义所有函数原型,主xx.c文件内include .h文件,编译的时候指定所有.c文件,比如 gcc xx.c a.c b.c d.c -o main
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-19 15:52:13 | 显示全部楼层
hrpzcf 发表于 2022-5-19 15:37
函数单独放.c文件,新建一个.h文件,定义所有函数原型,主xx.c文件内include .h文件,编译的时候指定所有.c ...

带点h的  在编译时 不用到对应的lib吗   我用你的办法并没有生成中间文件
直接就是一个EXE
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 17:03:34 | 显示全部楼层
本帖最后由 hrpzcf 于 2022-5-19 17:08 编辑
wp231957 发表于 2022-5-19 15:52
带点h的  在编译时 不用到对应的lib吗   我用你的办法并没有生成中间文件
直接就是一个EXE


要使用静态库lib的话,要改变编译方式。
1. 先把单独函数的 a.c b.c ... 文件生成编译成静态库 x.lib,百度;
2. 新建 .h 写上述.c文件的函数原型;
3. 主文件 xxx.c 中 include 有函数原型的 .h,把主文件和 x.lib 一起编译成完整的可执行文件,百度。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-19 17:58:32 From FishC Mobile | 显示全部楼层
hrpzcf 发表于 2022-5-19 17:03
要使用静态库lib的话,要改变编译方式。
1. 先把单独函数的 a.c b.c ... 文件生成编译成静态库 x.lib ...

我不是这个意思,换个问法,我们最常用的printf的实现部分在哪里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 18:37:41 | 显示全部楼层
wp231957 发表于 2022-5-19 17:58
我不是这个意思,换个问法,我们最常用的printf的实现部分在哪里
/lib/libc.so.6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 18:49:36 | 显示全部楼层
$ nm libc.so.6 | grep "\<printf\>"
0000000000074c04 T printf

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:00:21 | 显示全部楼层
$ nm lib/libc.so.6 | grep "\<printf\>"
0000000000074c04 T printf
$ 
0000000000074c04 <_IO_printf>:

/* Write formatted output to stdout from the format string FORMAT.  */
/* VARARGS1 */
int
__printf (const char *format, ...)
{
   74c04:        55                           pushq  %rbp
   74c05:        48 89 e5                     movq   %rsp,%rbp
   74c08:        48 81 ec e0 00 00 00         subq   $0xe0,%rsp
   74c0f:        48 89 bd 28 ff ff ff         movq   %rdi,-0xd8(%rbp)
   74c16:        48 89 b5 58 ff ff ff         movq   %rsi,-0xa8(%rbp)
   74c1d:        48 89 95 60 ff ff ff         movq   %rdx,-0xa0(%rbp)
   74c24:        48 89 8d 68 ff ff ff         movq   %rcx,-0x98(%rbp)
   74c2b:        4c 89 85 70 ff ff ff         movq   %r8,-0x90(%rbp)
   74c32:        4c 89 8d 78 ff ff ff         movq   %r9,-0x88(%rbp)
   74c39:        84 c0                        testb  %al,%al
   74c3b:        74 20                        je     74c5d <_IO_printf+0x59>
   74c3d:        0f 29 45 80                  movaps %xmm0,-0x80(%rbp)
   74c41:        0f 29 4d 90                  movaps %xmm1,-0x70(%rbp)
   74c45:        0f 29 55 a0                  movaps %xmm2,-0x60(%rbp)
   74c49:        0f 29 5d b0                  movaps %xmm3,-0x50(%rbp)
   74c4d:        0f 29 65 c0                  movaps %xmm4,-0x40(%rbp)
   74c51:        0f 29 6d d0                  movaps %xmm5,-0x30(%rbp)
   74c55:        0f 29 75 e0                  movaps %xmm6,-0x20(%rbp)
   74c59:        0f 29 7d f0                  movaps %xmm7,-0x10(%rbp)
  va_list arg;
  int done;

  va_start (arg, format);
   74c5d:        c7 85 30 ff ff ff 08         movl   $0x8,-0xd0(%rbp)
   74c64:        00 00 00 
   74c67:        c7 85 34 ff ff ff 30         movl   $0x30,-0xcc(%rbp)
   74c6e:        00 00 00 
   74c71:        48 8d 45 10                  leaq   0x10(%rbp),%rax
   74c75:        48 89 85 38 ff ff ff         movq   %rax,-0xc8(%rbp)
   74c7c:        48 8d 85 50 ff ff ff         leaq   -0xb0(%rbp),%rax
   74c83:        48 89 85 40 ff ff ff         movq   %rax,-0xc0(%rbp)
  done = __vfprintf_internal (stdout, format, arg, 0);
   74c8a:        48 8b 05 97 62 1d 00         movq   0x1d6297(%rip),%rax        # 24af28 <stdout@@GLIBC_2.2.5-0x1928>
   74c91:        48 8b 00                     movq   (%rax),%rax
   74c94:        48 8d 95 30 ff ff ff         leaq   -0xd0(%rbp),%rdx
   74c9b:        48 8b b5 28 ff ff ff         movq   -0xd8(%rbp),%rsi
   74ca2:        b9 00 00 00 00               movl   $0x0,%ecx
   74ca7:        48 89 c7                     movq   %rax,%rdi
   74caa:        e8 f0 4c 01 00               callq  8999f <__vfprintf_internal>
   74caf:        89 85 4c ff ff ff            movl   %eax,-0xb4(%rbp)
  va_end (arg);

  return done;
   74cb5:        8b 85 4c ff ff ff            movl   -0xb4(%rbp),%eax
}
   74cbb:        c9                           leaveq 
   74cbc:        c3                           retq   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-19 19:02:29 From FishC Mobile | 显示全部楼层
人造人 发表于 2022-5-19 18:49

那为什么只是引用stdio.h就可以访问这个lib里面的函数?这又是啥机制?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:05:11 | 显示全部楼层
$ ls
list.c  list.h  main.c
$ cat list.h
#ifndef _LIST_H_
#define _LIST_H_

#include <stddef.h>
#include <stdbool.h>

struct list_node_tag {
    void *data; size_t size;
    struct list_node_tag *next;
};

typedef struct {
    struct list_node_tag *head;
    size_t size;
} list_t;

list_t *list_init(void);
void list_deinit(list_t *list);
bool list_clean(list_t *list);
bool list_insert(list_t *list, size_t index, const void *data, size_t size);
bool list_delete(list_t *list, size_t index);
bool list_get(const list_t *list, size_t index, void *data, size_t size);
bool list_set(list_t *list, size_t index, const void *data, size_t size);
bool list_append(list_t *list, const void *data, size_t size);
size_t list_size(const list_t *list);
bool list_empty(const list_t *list);

#endif
$ cat list.c
#include "list.h"
#include <stdlib.h>
#include <memory.h>

list_t *list_init(void) {
    list_t *list = malloc(sizeof(*list));
    if(!list) return NULL;
    list->head = NULL;
    list->size = 0;
    return list;
}

void list_deinit(list_t *list) {
    if(!list) return;
    list_clean(list);
    free(list);
}

bool list_clean(list_t *list) {
    if(!list) return false;
    while(!list_empty(list)) list_delete(list, 0);
    return true;
}

bool list_insert(list_t *list, size_t index, const void *data, size_t size) {
    if(!list) return false;
    if(list_size(list) < index) return false;
    if(!data) return false;
    struct list_node_tag **current = &list->head;
    while(index--) current = &(*current)->next;
    struct list_node_tag *node = malloc(sizeof(*node));
    if(!node) return false;
    node->data = malloc(size);
    if(!node->data) {free(node); return false;}
    memcpy(node->data, data, size);
    node->size = size;
    node->next = *current;
    *current = node;
    ++list->size;
    return true;
}

bool list_delete(list_t *list, size_t index) {
    if(!list) return false;
    if(list_size(list) <= index) return false;
    struct list_node_tag **current = &list->head;
    while(index--) current = &(*current)->next;
    struct list_node_tag *temp = *current;
    *current = temp->next;
    free(temp->data); free(temp);
    --list->size;
    return true;
}

bool list_get(const list_t *list, size_t index, void *data, size_t size) {
    if(!list) return false;
    if(list_size(list) <= index) return false;
    if(!data) return false;
    struct list_node_tag *const *current = &list->head;
    while(index--) current = &(*current)->next;
    struct list_node_tag *temp = *current;
    if(temp->size > size) return false;
    memcpy(data, temp->data, temp->size);
    return true;
}

bool list_set(list_t *list, size_t index, const void *data, size_t size) {
    bool res = list_delete(list, index);
    return res ? list_insert(list, index, data, size) : res;
}

bool list_append(list_t *list, const void *data, size_t size) {
    if(!list) return false;
    return list_insert(list, list_size(list), data, size);
}

size_t list_size(const list_t *list) {
    if(!list) return 0;
    return list->size;
}

bool list_empty(const list_t *list) {
    if(!list) return true;
    return list_size(list) == 0;
}
$ cat main.c
#include "list.h"
#include <stdio.h>

void output(const list_t *list, size_t index) {
    if(index >= list_size(list)) return;
    output(list, index + 1);
    int temp; list_get(list, index, &temp, sizeof(temp));
    printf("%d ", temp);
}

int main(void) {
    list_t *list = list_init();
    for(size_t i = 0; i < 5; ++i) {
        int temp; scanf("%d", &temp);
        list_append(list, &temp, sizeof(temp));
    }
    output(list, 0); puts("");
    list_deinit(list);
    return 0;
}
$ gcc-debug -o main main.c list.c
$ ./main
1 2 3 4 5
5 4 3 2 1
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-19 19:08:50 From FishC Mobile | 显示全部楼层
人造人 发表于 2022-5-19 19:05

这个和我问的那个stdio的有关系吗?实在是没看懂啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:19:21 | 显示全部楼层
wp231957 发表于 2022-5-19 19:02
那为什么只是引用stdio.h就可以访问这个lib里面的函数?这又是啥机制?

stdio.h 里面就是有一个printf函数的声明,你自己声明一下printf函数,就不需要#include <stdio.h> 了

每一个c程序都会用到libc,你在编译代码的时候,即使你没有要求连接libc库,gcc也默认连接了这个库

$ cat main.c
//#include <stdio.h>

int printf(const char *format, ...);

int main(void) {
    printf("hello world!\n");
    return 0;
}
$ gcc-debug -o main main.c
$ ./main
hello world!
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:20:33 | 显示全部楼层
wp231957 发表于 2022-5-19 19:08
这个和我问的那个stdio的有关系吗?实在是没看懂啊
如何把若干个函数单独放在一个文件里


这个代码是我写的一个通用list
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:55:38 | 显示全部楼层
一个.c源文件到可执行文件其实是有好多步骤的
gcc一条命令就可以完成全部的任务,当然它也允许你在某一个位置停下来
$ ls
main.c
$ cat main.c
//#include <stdio.h>

int printf(const char *format, ...);

int main(void) {
    printf("hello world!\n");
    return 0;
}
$ cpp main.c >main.i          # 预处理
$ ls
main.c  main.i
$ gcc -S -o main.s main.i     # 编译
$ ls
main.c  main.i  main.s
$ as -o main.o main.s         # 汇编
$ ls
main.c  main.i  main.o  main.s
$ ld -o main main.o -dynamic-linker /lib/ld-linux-x86-64.so.2 /lib/Scrt1.o /lib/libc.so.6    # 连接
$ ls
main  main.c  main.i  main.o  main.s
$ ./main
hello world!
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-19 19:57:32 | 显示全部楼层
$ cat main.i
# 0 "main.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "main.c"


int printf(const char *format, ...);

int main(void) {
    printf("hello world!\n");
    return 0;
}
$ cat main.s
        .file        "main.c"
        .text
        .section        .rodata
.LC0:
        .string        "hello world!"
        .text
        .globl        main
        .type        main, @function
main:
.LFB0:
        .cfi_startproc
        pushq        %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq        %rsp, %rbp
        .cfi_def_cfa_register 6
        leaq        .LC0(%rip), %rax
        movq        %rax, %rdi
        call        puts@PLT
        movl        $0, %eax
        popq        %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size        main, .-main
        .ident        "GCC: (GNU) 12.1.0"
        .section        .note.GNU-stack,"",@progbits
$ objdump -S -M suffix main.o

main.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:        55                           pushq  %rbp
   1:        48 89 e5                     movq   %rsp,%rbp
   4:        48 8d 05 00 00 00 00         leaq   0x0(%rip),%rax        # b <main+0xb>
   b:        48 89 c7                     movq   %rax,%rdi
   e:        e8 00 00 00 00               callq  13 <main+0x13>
  13:        b8 00 00 00 00               movl   $0x0,%eax
  18:        5d                           popq   %rbp
  19:        c3                           retq
$ objdump -S -M suffix main

main:     file format elf64-x86-64


Disassembly of section .plt:

0000000000401000 <puts@plt-0x10>:
  401000:        ff 35 02 30 00 00            pushq  0x3002(%rip)        # 404008 <_GLOBAL_OFFSET_TABLE_+0x8>
  401006:        ff 25 04 30 00 00            jmpq   *0x3004(%rip)        # 404010 <_GLOBAL_OFFSET_TABLE_+0x10>
  40100c:        0f 1f 40 00                  nopl   0x0(%rax)

0000000000401010 <puts@plt>:
  401010:        ff 25 02 30 00 00            jmpq   *0x3002(%rip)        # 404018 <puts@GLIBC_2.2.5>
  401016:        68 00 00 00 00               pushq  $0x0
  40101b:        e9 e0 ff ff ff               jmpq   401000 <__abi_tag+0xcc0>

Disassembly of section .text:

0000000000401020 <main>:
  401020:        55                           pushq  %rbp
  401021:        48 89 e5                     movq   %rsp,%rbp
  401024:        48 8d 05 d5 0f 00 00         leaq   0xfd5(%rip),%rax        # 402000 <_start+0xfc0>
  40102b:        48 89 c7                     movq   %rax,%rdi
  40102e:        e8 dd ff ff ff               callq  401010 <puts@plt>
  401033:        b8 00 00 00 00               movl   $0x0,%eax
  401038:        5d                           popq   %rbp
  401039:        c3                           retq
  40103a:        66 0f 1f 44 00 00            nopw   0x0(%rax,%rax,1)

0000000000401040 <_start>:
  401040:        f3 0f 1e fa                  endbr64
  401044:        31 ed                        xorl   %ebp,%ebp
  401046:        49 89 d1                     movq   %rdx,%r9
  401049:        5e                           popq   %rsi
  40104a:        48 89 e2                     movq   %rsp,%rdx
  40104d:        48 83 e4 f0                  andq   $0xfffffffffffffff0,%rsp
  401051:        50                           pushq  %rax
  401052:        54                           pushq  %rsp
  401053:        45 31 c0                     xorl   %r8d,%r8d
  401056:        31 c9                        xorl   %ecx,%ecx
  401058:        48 c7 c7 20 10 40 00         movq   $0x401020,%rdi
  40105f:        ff 15 93 2f 00 00            callq  *0x2f93(%rip)        # 403ff8 <__libc_start_main@GLIBC_2.34>
  401065:        f4                           hlt
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-20 12:18:20 | 显示全部楼层


原来,没有头文件  真的能运行呀
int        printf (const char *__restrict, ...);
double sqrt (double);

int main()
{
    printf("a+b=%lf\n",sqrt(15));
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 14:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表