gcc与C程序常量变量的地址分配

一用gcc生成静态库和动态库

1hello实例

准备:

1创建一个目录

2hello代码

hello.h

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif//HELLO_H

hello.c

#include<stdio.h>
void hello(const char *name)
{
	printf("Hello %s\n",name);
}

main.c

#include"hello.h"
int main()
{
	hello("everyone");
	return 0;
}

3 gcc编译得到.o文件

在这里插入图片描述
在这里插入图片描述
静态库:

1创建静态库
在这里插入图片描述

2程序中使用静态库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3验证静态库的特点

在这里插入图片描述

动态库:

1创建动态库

在这里插入图片描述

2在程序中执行动态库

在这里插入图片描述

问题的解决方法:将libmyhello.so复制到目录/usr/lib中。由于运行时,是在/usr/lib中找库文件的。

在这里插入图片描述

静态库与动态库的比较:

gcc编译得到.o文件 gcc -c hello.c
创建静态库 ar -crv libmyhello.a hello.o
创建动态库 gcc -shared -fPIC -o libmyhello.so hello.o
使用库生成可执行文件 gcc -o hello main.c -L. -lmyhello
执行可执行文件 ./hello
在这里插入图片描述

2实例1使用库

代码:

A1.c

#include<stdio.h>
void print1(int arg)
{
	printf("A1 print arg:%d\n",arg);
}

A2.c

#include<stdio.h>
void print2(char *arg)
{
	printf("A2 printf arg:%s\n",arg);
}

A.h

#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif

test.c

#include<stdio.h>
#include"A.h"
int main()
{
	print1(1);
	print2("test");
	exit(0);
}

在这里插入图片描述

静态库:

在这里插入图片描述

错误解决方式:将test.c中的exit(0)修改为return 0。

动态库:

在这里插入图片描述

2实例2使用库

代码:

sub1.c

float x2x(int a,int b)
{
	float c=0;
	c=a+b;
	return c;
}

sub2.c

float x2y(int a,int b)
{
	float c=0;
	c=a/b;
	return c;
}

sub.h

#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

main.c

#include<stdio.h>
#include"sub.h"
void main()
{
	int a,b;
	printf("Please input the value of a:");
	scanf("%d",&a);
	printf("Please input the value of b:");
	scanf("%d",&b);
	printf("a+b=%.2f\n",x2x(a,b));
	printf("a/b=%.2f\n",x2y(a,b));
}

在这里插入图片描述

静态库:

在这里插入图片描述

动态库:

在这里插入图片描述

二Ubuntu、stm32下的程序内存分配问题(堆栈、局部全局变量)

代码:

//main.cpp
int a = 0; //全局初始化区
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main() {
    int b; //栈
    char s[] = "abc"; //栈
    char *p2; //栈
    char *p3 = "123456"; //123456\0在常量区,p3在栈上。
    static int c = 0; //全局(静态)初始化区
    p1 = (char *)malloc(10);
    p2 = (char *)malloc(20);
    //分配得来得10和20字节的区域就在堆区。
    strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
1Ubuntu环境下运行代码

在这里插入图片描述

2Keil运行试验代码

在这里插入图片描述

三总结

静态库要比动态库要小很多,生成的可执行文件大小也存在较小的差别。

ELF文件格式:

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

全局变量:在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件。

局部变量:定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数的内部就是无效的,再使用就会报错。

stm32中的堆栈:

单片机是一种集成电路芯片,集成CPU、RAM、ROM、多种I/O口和中断系统、定时器/计数器等功能。CPU中包括了各种总线电路,计算电路,逻辑电路,还有各种寄存器。

stm32 有通用寄存器 R0‐ R15 以及一些特殊功能寄存器,其中包括了堆栈指针寄存器。
当stm32正常运行程序的时候,来了一个中断,CPU就需要将寄存器中的值压栈到RAM里,然后将数据所在的地址存放在堆栈寄存器中。
等中断处理完成退出时,再将数据出栈到之前的寄存器中,这个在C语言里是自动完成的。
程序的内存分配:

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。它与数据结构中的堆是两回事,分配方式类似于链表。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后有系统释放

4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放

tack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。它与数据结构中的堆是两回事,分配方式类似于链表。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后有系统释放

4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放

5、程序代码区—存放函数体的二进制代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 很高兴为您解答。下面是C语言写一个Hello, world程序的代码: ``` #include <stdio.h> int main() { printf("Hello, world!\n"); return 0; } ``` 以上代码可以输出"Hello, world!"这句话。希望能够帮到您。 ### 回答2: C语言是一种结构化的编程语言,下面是一个简单的C语言程序,用于输出"Hello, world": ```c #include <stdio.h> int main() { printf("Hello, world\n"); return 0; } ``` 这个程序使用了标准输入输出库(stdio.h),并在主函数(main)中调用了一个printf函数。printf函数用于在控制台输出文本。在这个程序中,我们在printf函数中传入了一个字符串常量"Hello, world"作为参数,并使用\n表示换行。 程序的执行流程是由主函数的入口点开始。main函数被定义为整型,因此它的返回值类型是int。在这个程序中,我们使用return 0来表示程序正常运行结束。 要运行这个程序,需要安装C编译器(例如GCC),然后将代码保存为以.c为后缀名的文件,例如hello.c。然后打开命令提示符或终端,进入保存代码的目录,并编译运行该程序。具体命令为: ``` gcc hello.c -o hello ./hello ``` 编译命令gcc hello.c -o hello将源代码编译为可执行文件hello,然后通过./hello命令运行该可执行文件。程序将在终端输出"Hello, world"。 ### 回答3: #include<stdio.h> int main() { printf("Hello, World!"); // 输出Hello, World! return 0; } 这是一个C语言的Hello, World程序。首先,我们使用了#include<stdio.h>来包含了标准输入输出库的头文件,它定义了一些输入输出函数,例如printf()。接下来,我们定义了一个主函数main(),它是每个C程序的入口点。 在主函数中,我们使用printf()函数来打印出"Hello, World!"这个字符串。这个函数用来向屏幕输出文本或变量的值。最后,我们使用return 0;来结束程序并返回状态代码0,表示程序正常执行结束。编译和运行这个程序后,屏幕上会输出"Hello, World!"。这就是一个简单的Hello, World程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值