C语言--函数
C语言中include头文件的语法:#include<stdio.h>,先从系统include文件中寻找,再去项目include中寻找;
#include "my.h",先从项目include中寻找,再去系统include文件中寻找。
SV中include头文件的语法: `include "name_task.sv",同样先从当前仿真器目录中寻找,再去用户指定的其他地方寻找;
‘’include <name_task.sv>,从语言标准规定的搜索路径中寻找。
而且include只能在双引号中加绝对路径,一般都用双引号。
C语言中函数的定义: 返回值类型名 函数名(形参列表)
{函数体}
SV中函数的定义: (virtual) function 返回值类型名 函数名(形参列表)
{函数体}
返回值类型,void都表示空
SV中用display(默认加换行)和write(默认不加换行)来输出信息
memcpy函数,void *memcpy(void *dest, const void *src, size_t n);
两个void类型的指针,n表示byte数据长度,cpy的数据位长以byte为单位,不管指针类型被强制转换为何种类型。
memset函数,void *memset(void *s, int ch, size_t n);
在一段内存块中填充某个给定的值,在S开始后的n个字节的地址,用ch来替换值,
strcpy函数,char *(char *dest, const char *src);
两个char类型指针,cpy string,以"\0"标志结束,不管字符长度,所以字符长度不匹配时,会发生错误。
需要包含头文件,#include<string.h>
C语言中的string,只能用char *或者char name[]来表示。
printf中%c,输出字符。%s输出字符串。
printf中%lx才能输出64bit数据。
C语言中char表示有符号的字节,unsigned char表示无符号的字节变量。
SV与C之间传递数据,C的返回值只能是简单的int型,或者void类型,最好都通过参数来传递数据。
如果C与SV之间,通过open array传递数据,最好是C中和SV中,都有自己的空间,只通过data cpy的方式,来向SV中写入数据。
带指针的数据结构,在new时,应该malloc地址,来保证指针的大小范围。
SV中的动态数组,通过new来创建新空间,C中的地址空间,通过malloc/ralloc来创建
SV中定义16进制的数,32'hxxxx;C中定义16进制的数,0xXXXX;
C中的struct,如果存在一个*p指向一个struct,可以通过p->a来调用struct中的a元素。
等同的做法: (*p).a
如果是一个struct的变量,不能通过指向运算符,只能通过点来访问。struct p; p.a;
C中的全局变量是分配到内存中的静态存储区(static),(静态存储区在程序编译的时候,就会被创建好,用来存放静态数据,全局变量,程序整个运行期间都在)
(初始化的全局变量和静态变量是在一块区域,未初始化的全局变量和静态变量在相邻的另一区域)(程序结束后,系统释放)
形参等局部变量是被分配到内存中的动态存储区,叫做栈(stack),(空间分配由操作系统,处理器来决定,程序结束后,自动释放)
自己通过函数建立动态存储区,是建立在堆中(heap),(程序员控制,malloc/new创建,free/delete删除)
C程序还占有的空间有,文字常量区---常量字符串放在这里,程序结束后系统释放
程序代码区---存放函数体的二进制代码区
例子程序:
int a=0; //全局初始化区
char *p; //全局未初始化区
main() {
int b; //栈
char s[]="abc"; //栈
char *p2; //栈
char *p3 = "1234567"; //123456在常量区,p3在栈
static int c = 0; //全局(静态)初始化区
p1 = (char*)malloc(10); //分配10字节在堆区
p2 = (char*)malloc(20); //分配20字节在堆区
strcpy(p1, "123456"); //123456放在常量区,编译器可能将它与p3所指的"123456"优化为一个地方
}
堆与栈的区别,堆的地址空间在编译的时候,就可以确定下来,栈的地址空间只有在运行时,才能确定下来。
C语言中的printf想要选择性的打开debug信息:使用不定参数的宏定义(C99之后开始支持)。
#define DEBUG(format,...) printf(format,##__VA_ARGS__) (##的意思表示,如果可变参数被忽略或为空,处理器去电之前的那个逗号)
这样DEBUG就可以完全的替代printf。
其中还可以加入编译器内置的几个宏定义:
__LINE__:在源代码中插入当前源代码行号;
__FILE__:在源代码中插入当前源文件名;
__DATA__:在源代码中插入当前的日期;
__TIME__:在源代码中插入当前的编译时间;
编译器在进行源码编译时,会自动将这些宏替换。
#define DEBUG(format,...) printf("File:"__FILE__",Line:%05d:"format,__LINE__,##__VA_VARGS__)
在C语言中,要extern一个函数声明即可,然后这个函数在汇编中实现;
在汇编中,要EXPORT 把C语言定义的函数名引进来,再开始编写函数名开始的段;
#include <stdio.h>
extern int sum(int a, int b, int c, int d)
int main() {
int result = sum(1,2,3,4);
return 0;
}
EXPORT
ENTRY(sum)
ADD R0, R0, R1
ADD R2, R2, R3
ENDPROC