优快云 C/C++电子杂志第一期 之 可变参数学习笔记

优快云社区电子杂志项目(优快云 eMag)所有期刊总索引 优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群优快云社区电子杂志项目(优快云 eMag)现有杂志列表如下(排名不分先后): 《优快云社区电子杂志——Java杂志》《优快云社区电子杂志——C/C++杂志》《优快云社区电子杂志——ASP.NET杂志》《优快云社区电子杂志——Oracle杂志》《优快云社区电子杂志——移动开发杂志》《优快云社区电子杂志 阅读详情

前言:本文在很大程度上改编自网友kevintz的“C语言中可变参数的用法”一文,在行文之前先向这位前辈表示真诚的敬意和感谢。

一、什么是可变参数

我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为:

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

它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点“…”做参数占位符),实际调用时可以有以下的形式: printf("%d",i);

printf("%s",s);

printf("the number is %d ,string is:%s", i, s);    

以上这些东西已为大家所熟悉。但是究竟如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现,这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助.

 

二、写一个简单的可变参数的C函数

先看例子程序。该函数至少有一个整数参数,其后占位符…,表示后面参数的个数不定. 在这个例子里,所有的输入参数必须都是整数,函数的功能只是打印所有参数的值.

函数代码如下:

//示例代码1:可变参数函数的使用

#include "stdio.h"

#include "stdarg.h"

void simple_va_fun(int start, ...)

{

    va_list arg_ptr;

    int nArgValue =start;

    int nArgCout=0;     //可变参数的数目

    va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。

    do

    {

        ++nArgCout;

        printf("the %d th arg: %d/n",nArgCout,nArgValue);     //输出各参数的值

        nArgValue = va_arg(arg_ptr,int);                      //得到下一个可变参数的值

    } while(nArgValue != -1);               

    return;

}

int main(int argc, char* argv[])

{

    simple_va_fun(100,-1);

    simple_va_fun(100,200,-1);

       return 0;

}

下面解释一下这些代码

从这个函数的实现可以看到,我们使用可变参数应该有以下步骤:

⑴由于在程序中将用到以下这些宏:

void va_start( va_list arg_ptr, prev_param );

type va_arg( va_list arg_ptr, type );

void va_end( va_list arg_ptr );

va在这里是variable-argument(可变参数)的意思.

这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.

⑵函数里首先定义一个va_list型的变量,这里是arg_ptr,这个变

量是存储参数地址的指针.因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。

⑶然后用va_start宏初始化⑵中定义的变量arg_ptr,这个宏的第二个参数是可变参数列表的前一个参数,即最后一个固定参数.

⑷然后依次用va_arg宏使arg_ptr返回可变参数的地址,得到这个地址之后,结合参数的类型,就可以得到参数的值。

⑸设定结束条件,这里的条件就是判断参数值是否为-1。注意被调的函数在调用时是不知道可变参数的正确数目的,程序员必须自己在代码中指明结束条件。至于为什么它不会知道参数的数目,读者在看完这几个宏的内部实现机制后,自然就会明白。

 

(二)可变参数在编译器中的处理

我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的, 由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下面看一下VC++6.0中stdarg.h里的代码(文件的路径为VC安装目录下的/vc98/include/stdarg.h)

typedef char *  va_list;

#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define va_end(ap)      ( ap = (va_list)0 )

下面我们解释这些代码的含义:

1、首先把va_list被定义成char*,这是因为在我们目前所用的PC机上,字符指针类型可以用来存储内存单元地址。而在有的机器上va_list是被定义成void*的

2、定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统.这个宏的目的是为了得到最后一个固定参数的实际内存大小。在我的机器上直接用sizeof运算符来代替,对程序的运行结构也没有影响。(后文将看到我自己的实现)。

3、va_start的定义为 &v+_INTSIZEOF(v) ,这里&v是最后一个固定参数的起始地址,再加上其实际占用大小后,就得到了第一个可变参数的起始内存地址。所以我们运行va_start(ap, v)以后,ap指向第一个可变参数在的内存地址,有了这个地址,以后的事情就简单了。

这里要知道两个事情:

    ⑴在intel+windows的机器上,函数栈的方向是向下的,栈顶指针的内存地址低于栈底指针,所以先进栈的数据是存放在内存的高地址处。

    (2)在VC等绝大多数C编译器中,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:最后一个固定参数的地址位于第一个可变参数之下,并且是连续存储的。

|——————————————————————————|

|  最后一个可变参数             |   ->高内存地址处

|——————————————————————————|

   ...................

|——————————————————————————|

|  第N个可变参数              |     ->va_arg(arg_ptr,int)后arg_ptr所指的地方,

|                               |     即第N个可变参数的地址。

|——————————————— |    

   ………………………….

|——————————————————————————|

|  第一个可变参数               |     ->va_start(arg_ptr,start)后arg_ptr所指的地方

|                               |     即第一个可变参数的地址

|——————————————— |    

|———————————————————————— ——|

|                               |

|  最后一个固定参数             |    -> start的起始地址

|—————————————— —|       .................

|—————————————————————————— |

|                               | 

|——————————————— |  -> 低内存地址处

 

(4) va_arg():有了va_start的良好基础,我们取得了第一个可变参数的地址,在va_arg()里的任务就是根据指定的参数类型取得本参数的值,并且把指针调到下一个参数的起始地址。

因此,现在再来看va_arg()的实现就应该心中有数了:

#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

这个宏做了两个事情,

       ①用用户输入的类型名对参数地址进行强制类型转换,得到用户所需要的值

   ②计算出本参数的实际大小,将指针调到本参数的结尾,也就是下一个参数的首地址,以便后续处理。

(5)va_end宏的解释:x86平台定义为ap=(char*)0;使ap不再 指向堆栈,而是跟NULL一样.有些直接定义为((void*)0),这样编译器不会为va_end产生代码,例如gcc在linux的x86平台就是这样定义的. 在这里大家要注意一个问题:由于参数的地址用于va_start宏,所以参数不能声明为寄存器变量或作为函数或数组类型. 关于va_start, va_arg, va_end的描述就是这些了,我们要注意的 是不同的操作系统和硬件平台的定义有些不同,但原理却是相似的.

 

(三)可变参数在编程中要注意的问题

因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能 地识别不同参数的个数和类型. 有人会问:那么printf中不是实现了智能识别参数吗?那是因为函数 printf是从固定参数format字符串来分析出参数的类型,再调用va_arg 的来获取可变参数的.也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的. 例如,在C的经典教材《the c programming language》的7.3节中就给出了一个printf的可能实现方式,由于篇幅原因这里不再叙述。

(四)小结:

1、标准C库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址,编译器是不知道参数的实际数目的。

2、在实际应用的代码中,程序员必须自己考虑确定参数数目的办法,如

⑴在固定参数中设标志—— printf函数就是用这个办法。后面也有例子。

⑵在预先设定一个特殊的结束标记,就是说多输入一个可变参数,调用时要将最后一个可变参数的值设置成这个特殊的值,在函数体中根据这个值判断是否达到参数的结尾。本文前面的代码就是采用这个办法.

无论采用哪种办法,程序员都应该在文档中告诉调用者自己的约定。

3、实现可变参数的要点就是想办法取得每个参数的地址,取得地址的办法由以下几个因素决定:

①函数栈的生长方向

②参数的入栈顺序

③CPU的对齐方式

④内存地址的表达方式

结合源代码,我们可以看出va_list的实现是由④决定的,_INTSIZEOF(n)的引入则是由③决定的,他和①②又一起决定了va_start的实现,最后va_end的存在则是良好编程风格的体现,将不再使用的指针设为NULL,这样可以防止以后的误操作。

4、取得地址后,再结合参数的类型,程序员就可以正确的处理参数了。理解了以上要点,相信稍有经验的读者就可以写出适合于自己机器的实现来。下面就是一个例子

(五)扩展——自己实现简单的可变参数的函数。

下面是一个简单的printf函数的实现,参考了<The C Programming Language>中的156页的例子,读者可以结合书上的代码与本文参照。

#include "stdio.h"

#include "stdlib.h"

void myprintf(char* fmt, ...)        //一个简单的类似于printf的实现,//参数必须都是int 类型

{

    char* pArg=NULL;               //等价于原来的va_list

    char c;

   

    pArg = (char*) &fmt;          //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值

    pArg += sizeof(fmt);         //等价于原来的va_start         

 

    do

    {

        c =*fmt;

        if (c != '%')

        {

            putchar(c);            //照原样输出字符

        }

        else

{

//按格式字符输出数据

            switch(*++fmt)

{

            case 'd':

                printf("%d",*((int*)pArg));          

                break;

            case 'x':

                printf("%#x",*((int*)pArg));

                break;

            default:

                break;

            }

            pArg += sizeof(int);               //等价于原来的va_arg

        }

        ++fmt;

    }while (*fmt != '/0');

    pArg = NULL;                               //等价于va_end

    return;

}

int main(int argc, char* argv[])

{

    int i = 1234;

    int j = 5678;

   

    myprintf("the first test:i=%d/n",i,j);

    myprintf("the secend test:i=%d; %x;j=%d;/n",i,0xabcd,j);

    system("pause");

    return 0;

}

在intel+win2k+vc6的机器执行结果如下:

the first test:i=1234

the secend test:i=1234; 0xabcd;j=5678;

Qt制作大数据可视化大屏展示电子看板 Qt制作大数据可视化大屏展示电子看板 解决当前最火的大数据可视化大屏展示,整个项目通过Qt开发,集成了QML/QChart/ECharts及自定义控件等模块,所有的可视化控件都可以集成到其中。可以随意增加和减少模块,各个模块可以随意拖拽,整体可以个性化布局。模块标题栏可自定义,包括标题文本信息、文本颜色、宽度/高度、背景颜色、按钮个数等功能,满足各个样式需求。 实例中主要展示了现成的一些仪表盘... 阅读详情

相关推荐

(转)关于pipe()的详细解析

                                   kevintz 2000.8.23     int pipe(int fd[2])函数在内核生成一个管道,如图。返回的 fd[0]描述符用于从管道读内容,fd[1]用于向管道写。                ---------------------        fd[0]-----------

打印/传真嵌入式开发--张志龙的专栏 1435

41页PPT | 华为业务流程架构全景视图:全业务域L1-L3级流程全案

TBD、收集和生成线索、验证机会点、TBD、管理销售授权、管理销售项目、管理销售项目群、管理合同要素/模板、验证和分发线索、标前引导、管理开票和回款、客户网络评估、管理销售评审、TBD、管理交付项目群、管理合同文档、管理结构化合同信息、跟踪和培育线索、制定并提交标书、管理合同/PO变更、客户网络规划、管理销售决策。:4.1 管理技术、服务请求、4.2管理备件、服务交付、4.3管理非技术、服务请求、4.4管理客户、投诉。:管理Idea、产生Idea、激发兴趣与协作、孵化、原型和验证、确认Idea与商业化。

zuoan1993的博客 4550

主题:《Linux内核模块编程指南》(五)

主题:《Linux内核模块编程指南》(五)发信人: kevintz()整理人: kevintz(2000-06-24 00:40:31), 站内信件《Linux内核模块编程指南》《Linux Kernel Module Programming Guide》作者:Ori Pomerantz 中译者:谭志(lkmpg@21cn.com)

robinshaw的专栏 1203

相机基础知识讲解:CMOS和CCD

相机基础知识讲解:CMOS和CCD

Coppa的博客 5万+

基于大语言模型的多轮对话系统优化研究

基于大语言模型的多轮对话系统优化研究 摘要 本研究针对大语言模型在多轮对话场景中的性能衰减问题,提出了一套系统优化方案。通过分层存储架构(短期记忆层、中期摘要层、长期知识层)和混合检索策略优化上下文管理,设计动态槽位填充框架增强对话状态跟踪,引入熵引导的重置算法改进生成策略,并采用双路径加载架构突破I/O瓶颈。实验表明,该方案使任务完成率提升28.6%,响应一致性提高41.2%,推理延迟降低35.8%,为构建高性能智能对话系统提供了实用技术路径。 关键词:大语言模型;多轮对话;上下文管理;状态跟踪~~~~~

huanghm88的专栏 663

可变参数学习笔记

前言:本文在很大程度上改编自网友kevintz的“C语言中可变参数的用法”一文,在行文之前先向这位前辈表示真诚的敬意和感谢。一、什么是可变参数我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(

laomai的专栏 9239

【教程4>第8章>第44节】本章整体思维导图与学习总结

本教程系列提供FPGA/MATLAB/Simulink学习资源,包含《MATLAB入门100例》、《FPGA入门100例》、《Simulink入门60例》等基础教程,以及《FPGA/MATLAB/Simulink联合开发》进阶教程和《人工智能基础应用研究》专题,适合不同层次的学习者系统掌握相关技术。

FPGA/MATLAB学习教程/源码/项目合作开发 449

C中一种函数声明方式及可变参数函数讨论

本文部分原创,部分改编 可变参数函数改编自:网友kevintz的“C语言中可变参数的用法”一文 #include //引入可变参数函数头文件 #include //C语言中另一种函数声明方式 print(uint,buf,len) int uint; int buf; int len; { printf("Function Declaration another Way Result1

夜之流萤 451

芒果YOLO11改进17:即插即用 | 损失函数Repulsion Loss|Repulsion 解决目标遮挡场景下的目标检测,为解决密集人群检测中遮挡设计的损失函数,打造高效

即插即用 | 损失函数Repulsion Loss|Repulsion 解决目标遮挡场景下的目标检测,为解决密集人群检测中遮挡设计的损失函数,打造高效

包括YOLOv5、YOLOv7、YOLOv8等模型改进 484

Matlab 普通kriging(克里金)插值

Matlab 普通kriging(克里金)插值

dayuhaitang1的博客 4571

linux 管理 suid sgid 用法

一、UNIX下关于文件权限的表示方法和解析   SUID 是 Set User ID, SGID 是 Set Group ID的意思。   UNIX下可以用ls -l 命令来看到文件的权限。用ls命令所得到的表示法的格式是类似这样的:-rwxr-xr-x 。下面解析一下格式所表示的意思。这种表示方法一共有十位:   9 8 7 6 5 4 3 2 1 0 - r w x r

zheng195X的专栏 500

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

《优快云社区电子杂志——C/C++杂志》创刊号发布!

在C/C++杂志编辑团队和许多关心这本杂志的网友的共同努力下,《优快云社区电子杂志——C/C++杂志》创刊号顺利出刊,现在正式发布!让我们对他们的辛勤工作表示衷心的感谢!为杂志创刊号做出贡献的编辑和作者包括:(按字母顺序)ALNG,babysloth,carbon,cpluser,HappyParrot,jack,Jinhao,kxn,laomai,Polarislee,steedh

优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群 2万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

《优快云社区电子杂志——纯C论坛杂志》暨《纯C论坛·电子杂志》2005.1期(总第三期)发布!

下载:http://purec.binghua.com/Soft/Class2/dl_hpcem/200502/91.html-----------------------------------------------------------------------------------------------------------《优快云社区电子杂志——纯C论坛杂志》暨《纯C论坛·电子杂

潇寒的Blog 7623

csdn c/c++电子杂志第一期 之 c 眼看世界

C眼看世界汤韬 2004-11-4http://gcc.gnu.orgGCC 3.4.3发布。这个版本主要是修补一些小bug。更让我们关注的是,gcc 4将在不久后问世,据称GCC 4将带来编译速度的巨大提升,也会在语法上对C/C++作更完善的支持。Current release series: GCC 3.4.3 (released 2004-11-04) Branch

《优快云社区电子杂志——C/C++杂志》官方blog 7143

优快云电子杂志作者指南

杂志介绍优快云社区电子杂志项目由覆盖主流技术领域的一系列电子杂志组成。每种杂志都针对特定的技术领域,由专门的杂志编辑团队来负责。目前已经成立了编辑团队的杂志有:1、Oracle杂志2、MS-SQL Server杂志3、Java杂志4、C/C++杂志5、ASP.NET杂志6、Web开发杂志下一阶段计划创办的杂志有:1、C#杂志2、VB杂志3、Delphi

优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群 4万+

优快云 c/c++电子杂志第一期 之 从异步谈起

异步Jack 香港科技大学简介一般来说,简单的异步(Asynchronous)调用是这样一种调用方式:发起者请求一个异步调用,通知执行者,然后处理其他工作,在某一个同步点等待执行者的完成;执行者执行调用的实际操作,完成后通知发起者。可以看出,在异步调用中有两种角色:发起者和执行者,它们都是能主动运行的对象,我们称为主动对象,同时还有一个同步点,主动对象在同步点协调同步。在本文中,我

《优快云社区电子杂志——C/C++杂志》官方blog 6056

优快云社区电子杂志(eMag)官方blog群和官方邮箱

经过发展,优快云社区电子杂志项目(eMag)目前已经拥有15种电子杂志。 我们建立优快云社区电子杂志项目(eMag)官方blog群的目的在于,充分利用blog的各项功能,更好的展示各种杂志的成果,更好的展示编辑团队成员,更好的与我们的热心读者实现互动,更好的听取大家的意见。共同促进我们的杂志成长为专业、一流的电子刊物。 每种杂志都有自己的官方blog,它的主要功能包括:1.        在每

优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群 9667

优快云 c/c++电子杂志第一期 之 CPPUnit测试框架入门

□     工 具 使 用  文 / cpluser(Clean code that works.) 演示代码下载测试驱动开发(TDD,Test-Driven Development)是以测试作为开发过程的中心,它坚持,在编写实际代码之前,先写好基于产品代码的测试代码。开发过程的目标就是首先使测试能够通过,然后再优化设计结构。测试驱动开发式是极限编程的重要组成部分。xUni

《优快云社区电子杂志——C/C++杂志》官方blog 4894

优快云 C/C++电子杂志第一期 之 泛型函数指针类

Boost源码剖析:泛型函数指针类boost::function(修订版)                                       刘未鹏 /文                      C++的罗浮宫 (http://blog.csdn.net/pongba)  声明:2003年9月发表于《程序员》,本文较之有极大改动,特别在中后部分:-) 前奏 

《优快云社区电子杂志——C/C++杂志》官方blog 4520

优快云新年贺礼 eMag百花齐放

值此新春佳节即将到来之际,优快云倾力打造一系列的电子杂志,作为献给广大网友的新年贺礼。    感谢大家一直以来对我们的支持和厚爱。    此次发布的杂志列表如下,点击即可进入相关发布页面:    《优快云社区电子杂志——C/C++杂志》创刊号    《优快云社区电子杂志——ASP.NET杂志》创刊号    《优快云社区电子杂志——PB杂志》创刊号    《优快云社区电子杂

优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群 4万+

热烈庆祝优快云社区电子杂志(eMag)官方blog群建立

经过两个多月的发展,优快云社区电子杂志项目(eMag)目前已经拥有13种电子杂志。我们建立优快云社区电子杂志项目(eMag)官方blog群的目的在于,充分利用blog的各项功能,更好的对外展示各种杂志及其编辑团队,更好的与我们的热心读者实现互动,更好的听取大家的意见。共同促进我们的杂志成长为专业、一流的电子刊物。每种杂志都有自己的官方blog,它的主要功能包括:1、在每期杂志发布的同时,将

优快云社区电子杂志(优快云 eMag)——中国最全面、最专业的软件开发技术杂志群 1800
上一篇: 优快云 c/c++电子杂志第一期 之 CPPUnit测试框架入门
emag_cpp
博客等级 码龄22年 21粉丝 6原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值