8.1 函数第 8 章 函数与程序设计

文章内容源自《GPU编程与CG语言之阳春白雪下里巴人》,因笔者读书易中途放弃,遂每读一章节,将其移至简书平台,以此作为对自己读书的勉励。笔者用粗体斜体 标注了关键词句,望感兴趣的读者们一起学习共勉。猛戳这里查看更多!

第 8 章 函数与程序设计


通过第 5 章到第 7 章的阅读,我们已经知道了怎么声明变量(第 5 章),怎么写表达式和语句(第 6 章),怎么将输入 \ 输出参数绑定到语义词(第 7 章),本章将首先描述 Cg 语言中函数的写法,以及函数是否可以重载;然后阐述顶点 \ 片段着色程序中入口函数的概念(类似 C\C++中的 main()函数);最后,以 Cg 标准函数库来结束本章。

8.1 函数

函数可以被看作一个由用户定义的操作。Cg 语言中的函数声明形式与 C\C++中相同,由返回类型(return type)、函数名形参列表(parameter list,位于括号中,并用逗号分隔的参数表)和函数体组成。函数体包含在花括号中。 如果没有返回值,则函数的返回类型是 void。下面是函数定义的例子:

void myFunc(inout float val )
{ 
    ......
    val += 10.0;
}
 
float myFunc(float vals[])
{
    float sum = 0.0;
    ......
    return sum;
}

注意:如果函数没有返回值,函数的返回类型一定要是 void,否则编译会出现大量的错误,错误信息的大概形式是:

error C0000: syntax error, unexpected’(’at token “(”
error C0501: type name expected at token “(”
error C1110: function “main_v” has no return statement

参数传递机制是函数概念中的重中之重,请参阅 7.4 节“输入\输出修辞符”中的论述。此外,有一个比较特殊的函数形参类型,不论在 C\C++中还是在 Cg 语言中,都是一个令人头疼的话题,它就是数组形参

8.1.1 数组形参

在 C\C++中,当一个数组作为函数的形参时,实际上传入的只是指向首元素的指针,并且数组边界被忽略(参阅 stephen C.Dewhurst 所著的《C++必知必会》)。 而在 Cg 语言中不存在指针机制(图形硬件不支持),数组作为函数形参,传递的是数组的完整拷贝。关于 Cg 中形参数组的原始资料可以在文献[3]Array 章节中查到:

“The most important difference from C is that arrays are first-class types. That means array assignments actually copy the entire array, and arrays that are passed as parameters are passed by value, rather than by reference”.

这段英文中描述道,Cg 语言中数组是“first-class types”,中文翻译为“第一类数据类型”,所谓“第一类(first-class)”的含义是,强调该类型数据是“不可分解的、高级别的、不被重述的”,即“第一类数据类型”和“基础数据类型”的概念是近同的。如有兴趣深入了解“first-class”概念,可参阅 Matthieu Sozeau and Nicolas Oury 所著的“First-Class Type Classes”一文。

数组类型变量作为函数形参,可以是一维的也可以是多维的,并且不必声明数组长度,即 Unsized Array。例如:

float myFunc( float vals[])
{
    float sum = 0.0;
    for(int i = 0; i< vals.length; i++)
    {
        sum += vals[i];
    }
    return sum;
}

myFunc 是一个函数,输入一个数组变量,计算数组中所有数据之和,然后返回 float 类型数据。请注意:数组形参不必指定长度。如果指定了函数中形参数组的长度,那么在调用该函数时实参数组的长度和形参数组的长度必须保持一致,如果没有保持一致,编译时会出现错误提示信息:error C1102: incompatible type for parameter…

float myFunc( float vals[3])
{
    float sum = 0.0;
    for(int i = 0; i< vals.length; i++)
    {
        sum += vals[i];
    }
    return sum;
}
 
void main(…)
{
    float a[2] = {0.0, 1.0};
    float b[3] = {0.0, 1.0, 2.0};
    myFunc(a); //错误调用,会导致编译错误
    myFunc(b); //正确调用
}

对于函数的形参数组最好不要指定长度,这样就可以片配任意长度的参数数组。

如果函数的形参数组是多维数组,其声明方式和上面是一样的,可以不指定长度;如果指定形参数组长度,则实参数组长度必须保持一致。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我的技术专栏

图说C++对象模型:对象内存布局详解

40630
来自专栏Python小白进阶之旅

Python基本的排序算法比较,sorted的实现方法

简介:依次检查需要排序的列表,每次取出一个元素放入另一个排好序的列表中的适当位置。

10730
来自专栏阿凯的Excel

Python读书笔记19(函数与返回值)

为什么计算机与程序可以简化我们的工作量,因为我们只需要了解输入输出即可,不需要关心中间的计算过程。 那我们今天就聊一下如何使用函数输出返回值。 我们设想有一个函...

30160
来自专栏Golang语言社区

Go语言与面向对象编程

学习Go语言差不多快两个月了,感觉这个过程还是蛮快乐的,翻翻英文资料,写写小程序,总是觉得有好多东西都搞不明白,一步步走下来,却发现,这些迷惑好像也是不可或缺的...

45570
来自专栏我杨某人的青春满是悔恨

“身首异处”的序列(Swift)

声明:文章开头部分内容翻译自objc的一篇博客。当然,我并没有逐行翻译原文,只是说个大致意思,顺带阐述一些自己的理解和扩展思考,还有我自己的代码。

14720
来自专栏落影的专栏

程序员进阶之算法练习(三十四)LeetCode专场

LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 1、2、3题都是Medium的难度,大概是头条的面试题水准; 4、5题是Hard...

13830
来自专栏Golang语言社区

Go语言与面向对象编程

学习Go语言差不多快两个月了,感觉这个过程还是蛮快乐的,翻翻英文资料,写写小程序,总是觉得有好多东西都搞不明白,一步步走下来,却发现,这些迷惑好像也是不可或缺的...

34980
来自专栏Java帮帮-微信公众号-技术文章全总结

【Java提高二】三大特性-继承

【Java提高】三大特性-继承 在《Think in java》中有这样一句话:复用代码是Java众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够...

35690
来自专栏云飞学编程

Python学习,这些高阶函数和高阶特性值得一学

Python语言这么火,不论是对于刚开始学习的编程小白或者有接触过其他语言(c/c++/java等等)的同学来说,写代码的时候难免会受本身惯性思维或者其他语言的...

10630
来自专栏云霄雨霁

Java--集合类之Vector、BitSet、Stack、Hashtable

18470

扫码关注云+社区

领取腾讯云代金券