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

posted @ 2017-03-29 09:22  _9_8  阅读(487)  评论(0编辑  收藏  举报