精华内容
下载资源
问答
  • [color=#FF0000][/color]求助:请问可以[color=#FF0000]自定义函数[/color]中调用[color=#FF0000]结构体[/color]数组中的数据吗?
  • Java调用C语言动态库(JNA方式):回调函数结构体数组传参、结构体数组返回-附件资源
  • } 扩展资料: C语言结构体(struct)指的是一种数据结构,是C语言聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的...

    #include "stdio.h"

    struct abc{

    int a;

    int b;

    char *p;

    };

    struct abc myabc(void){

    struct abc n;

    n.a=2;

    n.b=3;

    n.p=(char *)0x00FF3304;

    return n;

    }

    void main(void)

    {

    struct abc x={1,2,(char *)0x00FF3300},y;

    y=myabc();

    printf("%d %d %p%d %d %p",x.a,x.b,x.p,y.a,y.b,y.p);

    }

    扩展资料:

    在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

    C++提供了许多种基本的数据类型(如int、float、double、char等)供用户使用。由于程序需要处理的问题往往比较复杂,而且呈多样化,已有的数据类型显得不能满足使用要求。C++允许用户根据需要自己声明一些类型,用户可以自己声明的类型还有结构体类型(structure)、共用体类型(union)、枚举类型(enumeration)、类类型(class )等,这些统称为用户自定义类型(user-defined type,UDT)。

    展开全文
  • c函数传递结构体数组

    千次阅读 多人点赞 2019-08-23 16:35:25
    结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。(结构体变量传递给函数与基本变量传递给函数类似...(结构体数组传递给函数与数组传...

    结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。(结构体变量传递给函数与基本变量传递给函数类似,可参考c函数传值调用和引用调用

    如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。(结构体数组传递给函数与数组传递给函数类似)

    一 形式参数

    形式参数是一个结构体指针

    void average(struct stu *ps, int len)

    {...}

    二 调用方式

    结构体数组名是一个指向结构体数组中第一个元素的常量指针,将结构体数组名(常量指针)传递给函数

    average(stus, len);

    三 案列展示

    #include <stdio.h>
    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    }stus[] = {
        {"Li ping", 5, 18, 'C', 145.0},
        {"Zhang ping", 4, 19, 'A', 130.5},
        {"He fang", 1, 18, 'A', 148.5},
        {"Cheng ling", 2, 17, 'F', 139.0},
        {"Wang ming", 3, 17, 'B', 144.5}
    };
    void average(struct stu *ps, int len);
    int main(){
        int len = sizeof(stus) / sizeof(struct stu);
        average(stus, len);
        return 0;
    }
    void average(struct stu *ps, int len){
        int i, num_140 = 0;
        float average, sum = 0;
        for(i=0; i<len; i++){
            sum += (ps + i) -> score;
            if((ps + i)->score < 140) num_140++;
        }
        printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
    }

     

    展开全文
  •  这里的难点就处理回调函数结构体数组参数,参数是从dll传出来的,java里面用指针接收,而获取结构体内部的每个值就需要用读内存的方式读取出来,这里就需要对结构体内存的存储方式比较了解才行,因为read...

    一、开发环境


    系统、开发环境:win7、eclipse 32位、jdk 32位、jre 32位

            由于这里使用的dll文件是32位的,而我本身的环境是64位的,包括eclipse、jdk、jre都是64位,所以这里需要开发环境共存(32位、64位共存),如果本来就是32位环境就不用重新搭建环境了。从以下连接分别下载32位软件:

    1.eclipse,不用安装,解压后即可使用,解压目录:D:\eclipse

    Eclipse IDE for Java EE Developers,   247 MB        Windows 32 Bit

    http://www.eclipse.org/downloads


    2.jdk 32位,安装目录:D:\Program Files\java\jdk32

    Windows x86 123.49MB       jdk-7u45-windows-i586.exe

    http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html


    3.jre 32位,安装目录:D:\Program Files\java\jre32

    Windows Offline(32-bit)     fileSize:   27.7MB

    http://www.java.com/en/download/manual.jsp


            要让32位和64位eclipse共存,需要修改eclipse目录下的文件:eclipse.ini
    在原环境变量(JAVA_HOME指向64位目录)不改变的情况下在上面文件内增加两行:
    -vm
    D:\Program Files\java\jdk32\bin\javaw.exe
    以上的作用使32位eclipse指向32位jdk。

    4.JNA下载,这里是放在百度云里面的,下载两个文件:jna-3.5.1.jar、platform-3.5.1.jar,放到目录:D:\Program Files\java\JNA_3.5.1
    http://pan.baidu.com/s/1iWobp

    至于JNA是什么,它本身是基于JNI技术的,然后进行封装以方便dll调用。这里不再详述,网上很多。


    二、调用方法


    1.简单函数调用

            关于jar包导入就不提了,创建工程:DemoTools,这里使用的dll是:libSDK.dll,把该文件放到工程目录下。
    dll提供的接口函数:
    int System_Init (int version, char* encoding);

    java代码->声明部分:
    import com.sun.jna.Library;  
    import com.sun.jna.Native;
    
    public class getSDK {
    	public interface Function extends Library {
    		Function instanceDll  = (Function)Native.loadLibrary("libSDK.dll",Function.class);
    		
    		public int System_Init(int version, String encoding);
    	}
    }

    java代码->调用部分:

    result = getSDK.Function.instanceDll.System_Init(1, "");

    参数类型比较简单时,调用也比较容易。

    2.回调函数调用

    当dll的接口函数需要回调函数作为参数时,使用以下方法实现:
    dll接口函数及回调函数类型:

    typedef void (*Callback_Status)(char *station_id, char *station_ip, int status);
    int Start_Server(char *ip, int port, Callback_Status fun);

    java代码->回调函数声明:
    import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
    
    public class getSDK {
    	public interface Callback_Status extends StdCallCallback {
    		public void Status(String station_id, String station_ip, int status);
    	}
    }
    java代码->回调函数实现:
    public class getSDK {
    	public static class Status_Realize implements Callback_Status{
    		public void Status(String station_id, String station_ip, int status) {
    			if (status == 2) {
    				GUI.Station_online(station_id, station_ip, 1, 0);
    			} else if (status == 3) {
    				GUI.Station_online(station_id, station_ip, 2, 0);
    			}
    		}
    	}
    }

    java代码->dll接口调用:
    public static getSDK.Callback_Status callback_status = new getSDK.Status_Realize();
    
    result = getSDK.Function.instanceDll.Start_Server("0.0.0.0", 1234, callback_status);

    3.回调函数含有结构体数组参数

    当回调函数其中一个参数是结构体数组时的处理方法:
    dll接口函数回调函数类型,结构体类型
    typedef struct result_data {
    	char Station_id[3];	
    	char Label_id[7];
    	int Signal;
    	int Power;
    	int Status;
    }Tstatus, *PTstatus;
    
    typedef void (*Callback_Data)(char *station_id, char *station_ip, Tstatus ret_data[], int count);
    
    int Start_Server (char *server_ip, int listen_port, Callback_Status callback_status, Callback_Data callback_data);
    
    java代码->回调函数、结构体定义:
    import com.sun.jna.Structure;
    public class getSDK {
    	public interface Function extends Library {
    		public static class Tstatus extends Structure {
    			public byte[] Station_id = new byte[3];
    			public byte[] Label_id = new byte[7];
    			public int Signal;
    			public int Power;
    			public int Status;
    
    			 public static class ByReference extends Tstatus implements
    			 Structure.ByReference {}
    			
    			 public static class ByValue extends Tstatus implements
    			 Structure.ByValue {}
    			
    			@SuppressWarnings({ "rawtypes", "unchecked" })
    			@Override
    			protected List getFieldOrder() {
    				List a = new ArrayList();
    				a.add("Station_id");
    				a.add("Label_id");
    				a.add("Signal");
    				a.add("Power");
    				a.add("Status");
    				return a;
    			}
    		}
    		public int Start_Server(String server_ip, int port, getSDK.Callback_Status Callback_Status,getSDK.Callback_Data Callback_Data);
    	}
    	public interface Callback_Data extends StdCallCallback {
    		public void Data(String station_id, String station_ip, Pointer data, int count);
    	}
    }

    java代码->回调函数实现:
    public class getSDK {
    	public static class Data_Realize implements Callback_Data{
    		public void Data(String station_id, String station_ip, Pointer data, int count) {
    			int srow, frow;
    			
    			srow = 0;
    			frow = 0;
    			
    			for (int i = 0; i < count; i++) {
    				byte[] stationbuf = new byte[2];
    				byte[] labelbuf = new byte[6];
    				int[] signal = new int[1];
    				int[] power = new int[1];
    				int[] status = new int[1];
    				
    				data.read(0 + i * 24, stationbuf, 0, 2);
    				data.read(3 + i * 24, labelbuf, 0, 6);
    				data.read(12 + i * 24, signal, 0, 1);
    				data.read(16 + i * 24, power, 0, 1);
    				data.read(20 + i * 24, status, 0, 1);
    				
    				String labelID = new String(labelbuf);
    				String stationID = new String(stationbuf);
    
    				GUI.message.append(String.valueOf(power[0]));
    				GUI.message.append(String.valueOf(signal[0]));
    				GUI.message.append(String.valueOf(status[0]));
    			}
    		}
    	}
    }

    java代码->接口调用:
    public static getSDK.Callback_Status callback_status = new getSDK.Status_Realize();	
    public static getSDK.Callback_Data callback_data = new getSDK.Data_Realize();
    
    result = getSDK.Function.instanceDll.Start_Server("0.0.0.0", 1234, callback_status, callback_data);

            这里的难点就在处理回调函数的结构体数组参数,参数是从dll传出来的,java里面用指针接收,而获取结构体内部的每个值就需要用读内存的方式读取出来,这里就需要对结构体在内存中的存储方式比较了解才行,因为read函数需要指定:内存起始位置、接收数据数组变量、数组变量的第几个元素、取内存大小,4个参数。
    上面源码中i*24作用是取到结构体数组的第二、第三、、、个元素。也就是这里的结构体占内存大小为24,看下面:
             在32位系统中char占1个字节,int占4个字节,算下来结构体TStatus应该是22个字节,实际上还有一个内存对齐的概念,结构体前两个char数组共10个字节(是连续存储的),而结构体分配内存的大小必须是该结构体中占字节最大类型的倍数,所以应该分配4字节的倍数即12字节,所以前两个char数组实际分配了12个字节,在取数据时,第三个int的偏移量是12,整个结构体的大小为12 + 3*4(三个int变量)= 24字节

    4.接口函数参数为结构体数组

    当接口函数的参数为结构体数组,并且结构体成员也为结构体数组时,调用方法:
    dll接口函数 类型,结构体类型
    typedef unsigned int UINT;
    
    typedef struct code_word {
    	char Feild[8];
    	BOOL Inverse;
    	UINT Length;
    	CHAR Payload[255];	
    }Cword, *pCword;
    
    typedef struct label_data {
    	char Label_id[7];
    	UINT Count;
    	Cword NCword[50];
    }Ldata, *pLdata;
    
    int Start_Update (char *station_id, int count, Ldata data[]);

    java代码->结构体定义,接口函数声明:
    public class getSDK {
    	public interface Function extends Library {
    		public static class Cword extends Structure {
    			public byte[] Feild = new byte[8];
    			public boolean Inverse;
    			public int length;
    			public byte[] Payload = new byte[255];
    
    			 public static class ByValue extends Cword implements 
    			 Structure.ByValue {}
    
    			@SuppressWarnings({ "rawtypes", "unchecked" })
    			@Override
    			protected List getFieldOrder() {
    				List a = new ArrayList();
    				a.add("Feild");
    				a.add("X_coord");
    				a.add("Y_coord");
    				a.add("Font");
    				a.add("Inverse");
    				a.add("length");
    				a.add("Payload");
    				return a;
    			}
    		}
    
    		public static class Ldata extends Structure {
    			public byte[] Label_id = new byte[7];
    			public int Count;
    			public Cword.ByValue[] NCword = new Cword.ByValue[50];
    
    			public static class ByReference extends Ldata implements
    					Structure.ByReference {
    			}
    
    			public static class ByValue extends Ldata implements
    					Structure.ByValue {
    			}
    
    			@SuppressWarnings({ "rawtypes", "unchecked" })
    			@Override
    			protected List getFieldOrder() {
    				List a = new ArrayList();
    				a.add("Label_id");
    				a.add("Patten");
    				a.add("Count");
    				a.add("NCword");
    				return a;
    			}
    		}
    		public int Start_Update(String station_id, int count, Ldata.ByValue[] data);
    
    	}
    }

    java代码->接口函数调用:
    public class GUI {
    	public static int labelcount = 5;
    	
    	public static String[] labellist = new String[]{"000834","000835","041908",
    		"041909","04190A","04190B","04190C","04190D","04190E","04190F","041910",
    		"041911","041912","041913","041914","041915","041916","041917","041918"};
    
    		bsend.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				int i;
    				int result;
    			    
    				getSDK.Function.Ldata.ByValue tdata = new getSDK.Function.Ldata.ByValue();
    				getSDK.Function.Ldata.ByValue[] data = (getSDK.Function.Ldata.ByValue[])tdata.toArray(labelcount);
    				
    				for (i = 0; i < labelcount; i++) {
    					data[i].Label_id = labellist[i].getBytes();
    				}
    				
    				for (i = 0; i < labelcount; i++) {
    					data[i].Count = 4;
    				}
    
    				getSDK.Function.Cword.ByValue cdata = new getSDK.Function.Cword.ByValue();
    				getSDK.Function.Cword.ByValue[] ctdata = (getSDK.Function.Cword.ByValue[])cdata.toArray(50);
    				
    				ctdata[0].Feild = "Text".getBytes();
    				ctdata[0].Inverse = false;
    				ctdata[0].length = "test".getBytes().length;
    				ctdata[0].Payload = "test".getBytes();
    			
    				ctdata[1].Feild = "Text".getBytes();
    				ctdata[1].Inverse = false;
    				ctdata[1].length = "hello".getBytes().length;
    				ctdata[1].Payload = "hello".getBytes();
    				
    				ctdata[2].Feild = "Text".getBytes();
    				ctdata[2].Inverse = false;
    				ctdata[2].length = "单位".getBytes().length;
    				ctdata[2].Payload = "单位".getBytes();
    				
    				ctdata[3].Feild = "Text".getBytes();
    				ctdata[3].Inverse = false;
    				ctdata[3].length = "规格".getBytes().length;
    				ctdata[3].Payload = "规格".getBytes();
    				
    				for (i = 0; i < labelcount; i++) {
    					data[i].NCword = ctdata;
    				}
    				
    				result = getSDK.Function.instanceDll.Start_Update((String)station.getSelectedItem(), labelcount, data);
    			}
    		});
    }

            这里比较关键的是结构体数据的定义,结构体声明中有两个方法:ByValue 和 ByReference, 分别是值和引用,这里使用ByValue方式创建结构体,然后在通过toArray的方式生成结构体数组,为的是保证定义的数组是内存连续的,如果这里直接用:
    getSDK.Function.Ldata.ByValue[] tdata = new getSDK.Function.Ldata.ByValue[labelcount];
    的方式,得到的内存是不连续的,当你传递这种方式定义的变量给dll时,dll只能取到第一个结构体元素的值,造成数据丢失。

    展开全文
  • 话不多说,上代码 函数调用数组  #include void main() { void f1(int a); void f2(int x[]);... int a[10] = { 0,1,2,3,4,5,6...//函数调用数组数组名存的就是数组首地址) } void f1(int a)//就像调用一个变量一
    话不多说,上代码


    函数调用数组 (数组*函数)

    #include<stdio.h>
    void main()
    {
    	void f1(int a);//【声明
    	void f2(int x[]);
    
    	int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
    	f1(a[9]);//函数【调用数组元素
    	f2(a);//函数【调用数组(数组名存的就是数组首地址)
    }
    
    void f1(int a)//就像调用一个变量一样【数组元素在此就是单个变量
    {
    	printf("%d\n", a);
    }
    
    void f2(int x[])//调用一个地址(所以函数内对数组做的改变全是真实改动)
    {
    	printf("%d\n", x[9]);
    }
    请注意其对应的:声明、定义、调用。的区别!
    调用数组只需传入数组名(数组首地址)即可。
    而调用数组元素则是采用"值传递"那样的方式,就像调用一个不是数组的变量一样。

    声明、定义 中做参数【都是函数首部】

    void f2(int x[]);//声明
    
    void f2(int x[])//定义
    {
    	printf("%d\n", x[9]);
    }

    调用 中做参数【直接是数组名(首地址)】

    f2(a);//调用(a是数组a[100]的数组名)


    指针数组(数组*指针)

    #include<stdio.h>
    void main()
    {
    	int i = 0;
    	char *p[4];//int (*p)[4]则是指向一维数组的指针变量
    	p[0] = "hello";//指针能直接指向字符串并且赋值,比字符数组好用多了(这首指针p[0],是一个指针变量)
    	p[1] = "world";
    	p[2] = "!";
    	p[3] = "\1";
    	while(p[i]!="\1")//字符串就是地址?详见另一文章
    	{
    		printf("%s\n",p[i]);//此处记住,输出的参数是字符串的地址
    		i++;
    	}
    	
    }


    结构体数组(数组*结构体)

    #include<stdio.h>
    #include<string.h>
    struct Man 
    	{
    	int num;
    	char name[20];
    	}Student[3];
    
    void main()
    {
    	for (int i = 0; i < 3; i++)
    	{
    		Student[i].num = i;
    		strcpy(Student[i].name, "zhang");//还不能直接用等号= =。。。
    		printf("学生%d %s\n", Student[i].num , Student[i].name);
    	}
    }





    展开全文
  • 见代码  1 #include &lt;stdio.h&gt;  2 typedef int (*Fun)(); //函数指针  3 struct student ... //函数指针,存放的应该是函数的入口地址  7 };  8   9 int fun1(int a)  10 {  11 print...
  • 在函数中利用scanf为结构体数组赋值

    万次阅读 2016-11-11 17:54:43
    结构体数组指针作为函数参数,通过数组的首地址与偏移量对结构体数组进行scanf的赋值,在函数中通过指针间接访问到其指向的内存 程序当中,编写函数,输入5个学号(int),5个姓名(字符串),5个成绩数组(每...
  • 创建结构体数组 下面的示例说明了如何创建结构体数组。结构体是使用被称为字段的数据容器将相关数据组合一起的一种数据类型。每个字段都可以包含任意类型或任意大小的数据。将记录存储含有字段name、billing和...
  • 示例代码: #include"stdio.h" #include"stdint.h" ...struct jiegouti//这是个结构体 { int8_t paraone;//第一个参数 uint8_t paratwo;//第二个参数 uint16_t parathree;//第三个参数 hansh...
  • MATLAB定义结构体数组 最近使用MATLAB代码生成,结构体数组的问题困扰许久,先将支持代码生成的结构体数组创建方法总结如下,主要参考MATLAB帮助文档。 0. MATLAB的结构体 结构体是使用被称为字段的数据容器将...
  • Matlab中访问结构体数组中的数据

    千次阅读 2020-06-11 21:50:15
    目录 访问结构体数组中的数据 1.访问标量结构体中的数据 2.通过对结构体数组进行索引来访问数据 访问结构体数组中的数据 该示例演示了如何访问结构体数组的...
  • 项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport传入从DLL引入函数就可以了。但是当传递的是结构体、结构体数组或者结构体指针的时候,就会发现C#上没有类型可以对应。这时怎么办,...
  • //用结构体数组指针完成:有三个学生信息,存放在结构体数组中,要求输出全部信息 #include struct Stu { int num; char name[20]; char sex; int age; }; int main() { struct Stu student[3]={{317,"han",'m'...
  • 结构体&结构体数组

    万次阅读 多人点赞 2018-08-16 18:17:39
    1、结构体的定义 struct 结构体类型名 { 类型名 成员名; 类型名 成员名; …… }; 先声明结构体类型,再定义结构体变量名 声明结构体类型,不分配空间 定义结构体类型变量,就要分配内存空间 1)结构体被...
  • #include num_jh.h //函数的分文件编写 int a_fwj = 10; int b_fwj = 20; num_jh(a_fwj, b_fwj);//调用了头文件num_jh.h
  • void chg_state(uint8 cur_state) {  uint8 i;  static uint8 last_state=INVALID;    plc_state.wait_t = 0;  plc_state.init=1;  for(i = 0; i  ... if(plc_state_slot[i].c
  • C++使用结构体数组作为函数参数

    千次阅读 2020-06-25 09:51:01
    写C++的时候,当使用一个数组作为函数参数传入的时候,数组自动转化成指针变量。 int arr[] = {1,2,3}; //arr++; //这里错误 void printArr(arr[]) { arr++; //正确 } 因此在函数内部修改形参数组时,实参也会...
  • 一:结构体指针 指向结构体变量的指针,称为结构体指针 Stu stu1={0}; Stu *p=&stu1; 这里Stu*:表示结构体指针类型(类型) p:表示结构体指针变量(变量名) &stu1:表示结构体变量地址...二:结构体数组与指针的关系
  • C语言结构体数组实例

    千次阅读 2019-08-23 20:15:34
    今天我看到一个项目关于结构体数组函数是这么用的,总结出来 结构体数组 + 结构体成员是函数指针; 可以根据需求自己判断,并调用相应的函数,实现想要的功能。 比如:根据不同的名字的判断,去告诉我想要对每个...
  • 结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)。请看下面的一个例子: struct stu{ char name[]; //姓...
  • printf("结构体函数调用测试o(∩_∩)oOK\n"); return 0; } struct mode { int num; char null; }; int main(void) {  int i;  //结构体指针与结构体数组  struct ...
  • 调用函数时实际传递的是一个指针,所以函数的形参实际上是一个指针,但为了使程序员新手更容易上手一些,编译器也接受数组形式的函数形参。因此,下面这两个函数原型是相等的: int strlen(char *string); int ...
  • 结构体数组

    千次阅读 2009-03-22 11:48:00
    结构体类型数组与基本类型数组的定义与引用规则是相同的,区别在于结构体数组中的所有元素均为结构体变量。结构体变量有三种定义方法,因此结构体数组也具有三种定义方法,如下:方式1:struct 结构体标
  • C#调用C/C++动态库 封送结构体,结构体数组 一.结构体的传递 Cpp代码 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int osVersion; int majorVersion; int minorVersion...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 121,677
精华内容 48,670
关键字:

如何在函数中调用结构体数组