此处将为大家介绍关于PHP行为和数组指针的详细内容,并且为您解答有关php行为和数组指针的区别的相关问题,此外,我们还将为您介绍关于10、C语言——指针与一维数组(指针数组与数组指针)、c#–如何编组
此处将为大家介绍关于PHP行为和数组指针的详细内容,并且为您解答有关php行为和数组指针的区别的相关问题,此外,我们还将为您介绍关于10、C语言 —— 指针与一维数组(指针数组与数组指针)、c# – 如何编组指向结构数组指针的指针?、C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针、c语言中数组,指针数组,数组指针,二维数组指针的有用信息。
本文目录一览:- PHP行为和数组指针(php行为和数组指针的区别)
- 10、C语言 —— 指针与一维数组(指针数组与数组指针)
- c# – 如何编组指向结构数组指针的指针?
- C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
- c语言中数组,指针数组,数组指针,二维数组指针
PHP行为和数组指针(php行为和数组指针的区别)
each()
功能)并遇到以下警告:
Caution
Because assigning an array to another variable resets the original array’s pointer,our example above would cause an endless loop had we assigned $fruit to another variable inside the loop.
一个例子:
<?PHP $fruit = array('a' => 'apple','b' => 'banana','c' => 'cranBerry'); reset($fruit); while (list($key,$val) = each($fruit)) { echo "$key => $val\n"; } ?>
好的.这说得通.但我决定做一个简单的测试:
<?PHP $fruit = array('a' => 'apple','c' => 'cranBerry'); foreach ($fruit as $key => $name) { printf("[%s] => [%s]\n",$key,$name); } $fruit2 = $fruit; echo current($fruit); ?>
结果是预期的:指针已被重置.我的问题是指针是否仅在数组结束后重置?
例如:
<?PHP $fruit = array('a' => 'apple',$name); } reset($fruit); next($fruit)."\n"; $fruit2 = $fruit; echo current($fruit); ?>
指针保留在第二个数组元素中(‘b’=>’banana’).
这种行为是语言的特征吗?
谢谢你,对不起英语不好意思.
解决方法
This behavior is characteristic of language?
PHP数组中“指针”的含义与“指针”的一般含义不同(在C/C++或其他语言中,程序员可以直接访问内存).
PHP中没有指针. array数据类型将光标内部保留在其包含的值列表中.它被称为数组的内部指针,它由函数reset()
,next()
,prev()
,end()
,each()
以及其他函数修改.它可以用于迭代数组,如下所示:
$array = array(1,2,3); while (list($key,$val) = each($array)) { echo($key.' => '.$val."\n"); }
没有可靠的方法来使用next()
或prev()
迭代数组,因为当没有更多元素要迭代时它们返回FALSE但是当值FALSE作为元素存储在数组中时它们也返回FALSE.
如果您只需要从数组的开头(或结尾)分析几个项目,它们可能很有用. F.E.假设我们有一个由函数返回的整数数组,我们需要得到第一个不为零的值.
但使用foreach()可以更轻松地实现这一目标:
$array = array(0,1,3); foreach ($array as $val) { if ($val != 0) { break; } } echo($val); // prints "2"
或array_shift():
$array = array(0,3); do { $val = array_shift($array); if ($val != 0) { break; } } while(count($array)); echo($val); // prints "2"
The result is expected: the pointer has been reset. My question is if the pointer is reset only after the end of the array?
foreach()
的文档是错误的.也许它在PHP 3和PHP 4上是正确的,但我认为自从PHP 5中引入iterators以来,foreach()
的行为发生了变化(更好).
它说:
When foreach first starts executing,the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
As foreach relies on the internal array pointer,changing it within the loop may lead to unexpected behavior.
一个简单的测试与此陈述相矛盾:
$array = array(1,3,5,7,9); foreach ($array as $val1) { foreach ($array as $val2) { echo('$val1='.$val1.'; $val2='.$val2.'; '); } echo("\n"); }
它没有问题.如果foreach()使用内部数组指针,它应该不起作用.它可能会创建指针的副本.
您还可以尝试在foreach()中使用current(),next(),prev()或reset(),您将获得令人惊讶且有时不一致的结果.
最好使用foreach()迭代数组,不要以任何方式依赖内部指针.
但是,当您需要获取数组的第一个和最后一个元素而不必担心键时,函数reset()和end()非常方便.
10、C语言 —— 指针与一维数组(指针数组与数组指针)
1、使用指针修改数组元素
int array[2];
int *p;
p = array;
// 或 p = &a[0];
*p = 10;
printf("a[0]=%d\n", a[0]); // 输出:a[0]=10
2、使用指针遍历数组
// a、平常我们是这样遍历数组的
int array[3] = {1, 2, 3};
for(int i=0; i<3; i++) {
printf("a[%d]=%d\n", i, a[i]);
}
// b、用指针可以这样遍历数组
// 如果 p 是指向数组array的首元素array[0]
// 那么 p+1 则会根据数据类型 int 从而指向数组array的第二个元素array[1]
// 在16位编译器环境下,p+1代表增加2个字节
int *p = array;
for(int i=0; i<3; i++) {
printf("a[%d]=%d\n", i, *(p+i));
}
// c、指针遍历2
// 此种方法相比于上一种方法不同的是:上一种方法指针p不变,而这种p每循环一次就改变一个
for(int i=0; i<3; i++) {
printf("a[%d]=%d\n", i, *(p++));
}
// d、指针遍历3
// 数组跟指针有着密不可分的关系,array[i]也可以写成*(array+i)
for(int i=0; i<3; i++) {
printf("a[%d]=%d\n", i, *(array+i));
}
3、指针,数组与函数参数
// 定义一个修改数组首元素的函数
void change(char c[]) {
c[0] = 0;
}
void main() {
char a[3];
change(a); // 传入数组地址
printf("a[0]=%d\n", a[0]); // 输入:a[0]=10
}
// 也可传入指针
void main() {
char a[3];
char *p = a;
change(p); // 传入地址
printf("a[0]=%d\n", a[0]); // 输入:a[0]=10
}
// 当然,change函数还可以改成这样
void change(char *c) {
*c = 10;
// 或c[0] = 10;
}
4、指针数组与数组指针
a、指针数组:int *p[n];
因为优先级:() > [] > *
p首先是一个数组,再由 int * 说明这是一个整型指针数组
即数组里的元素都存放着变量的地址
b、数组指针(行指针):int (*p)[n];
p是一个指针,指向一个整型的一维数组
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
// 所以数组指针也称指向一维数组的指针,亦称行指针。
c# – 如何编组指向结构数组指针的指针?
int myData(uint myHandle,tchar *dataname,long *Time,uint *maxData,DATASTRUCT **data); typedef struct { byte Rel; __int64 Time; char Validated; unsigned char Data[1]; } DATASTRUCT ;
我的C#声明如下:
[DllImport("myData.dll",EntryPoint = "myData")] public static extern int myData(uint myHandle,[MarshalAs(UnmanagedType.LPTStr)] string dataname,out long Time,out uint maxData,ref DATASTRUCT[] data); [StructLayout(LayoutKind.Sequential,Pack = 1)] public struct DATASTRUCT { public sbyte Rel; public long Time; public byte Validated; public double Data; }
然后我调用托管函数如下:
string dataToShow = "description"; long Time; uint maxData; // How many structs will be returned,i.e. how much data is available uint myHandle = 1; DATASTRUCT[] datainformation = new DATASTRUCT[3]; // doesn't matter what I specify as the array size? myData(myHandle,dataToShow,out Time,out maxData,ref datainformation);
在执行时,即使有3个返回,上述函数也将成功返回只有一个结构.为什么会这样?
附加信息;我试过通过以下方式将指针传递给结构数组的指针:
- ref DATASTRUCT[] data; // Works but only returns one struct - [Out,MarshalAs(UnmanagedType.LPArray)] DATASTRUCT[] data; // returns the number of defined structs with garbage
据我了解,我可能需要使用IntPtr进行一些手动编组,但我不知道如何实现这一点,所以任何建议都将受到赞赏.
解决方法
将您的API定义更改为(注意,我将maxData参数更改为uint,.NET中为64位,本机为32位).
[DllImportAttribute("myData.dll",out uint Time,out IntPtr pData);
我不记得你是否需要最后一个参数的out关键字,但我想是的.
然后,调用myData:
uint nAllocs = 0,time = 0; IntPtr pAllocs = IntPtr.Zero; myData(1,"description",out time,out nAllocs,out pAllocs);
现在,pAllocs应该指向非托管内存,将这些内容编组到托管内存中并不太难:
[StructLayoutAttribute(LayoutKind.Sequential,Pack = 1)] public struct DATASTRUCT { public byte Rel; public long Time; public byte Validated; public IntPtr Data; //pointer to unmanaged string. } int szStruct = Marshal.SizeOf(typeof(DATASTRUCT)); DATASTRUCT[] localStructs = new DATASTRUCT[nAllocs]; for(uint i = 0; i < nallocs; i++) localStructs[i] = (DATASTRUCT)Marshal.PtrToStructure(new IntPtr(pAllocs.ToInt32() + (szStruct * i)),typeof(DATASTRUCT));
现在你应该有一系列本地结构.
需要注意的一点您可能需要将项目设置为编译为x86,以将IntPtr的大小标准化为4字节(DWORD)而不是Anycpu的默认值8.
C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
普通变量和指针变量
共性
PS:
可见这4个函数的汇编指令完全一致,无论是什么类型的指针变量,对指针变量的读写跟普通变量没有任何区别,所谓的指向只是描述指针变量的值时多少而已,就读写而言,指针变量跟普通变量没有任何区别。
特性
普通变量的值常常用于数学计算,而指针变量常常用来定位内存。
普通变量可以不赋初值,但是指针变量的初值必须万分慎重,因为未来的*操纵会以这个初值为目标内存地址,往里面读写数据(可以才C primer plus中看到相应分析)
所以给指针变量赋值一定要是合法合理的内存地址,读取非法的地址程序会修改其他的内存中的值导致程序崩溃,野指针。
空指针和野指针
野指针:定义了一个指针变量,如果没有进行初始化,系统就会有可能随机赋值一个地址给这个指针变量,也就是说,这个指向指向一个未知的区域。
空指针:空指针不是指向常数0,只指向地址0,即NULL,其实换句话说,指针的本质就是地址嘛,空指针就是指针本身的值(地址)为0空指针的作用是防止野指针的出现,因为我们不能知道野指针到底指向哪里,所以我们也无法判断一个指针是否是野指针,这样很危险,但如果养成将指针初始化为空指针的习惯,我们就能判断出这个指针是不是有效的(判断是不是NULL就可以了)通用指针一般都用在函数传参,实现所谓的“多态”,但到函数里面使用时,一般还是被转换成具体类型的指针。
指针变量的+-运算
指针变量的加减运算:也就是做地址偏移,不同 的指针类型偏移的步长不同。
PS:
区分指针数组
int *a[3]
和数组指针int (*a)[3]
,前者时存放指针的数组,后者是指向数组的指针。
指针数组和数组指针
int *b
可以用来定义数组
int a = [1,2,3,4,5];
int *b = a;
int (*b)[5]
用来指向数组
int a = [1,2,3,4,5];
int (*b)[5] = a;
int *b[5]
用来存放指针
int *b[5] =[&a,&b,&c,&d,&e] ;
数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]…p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 p=a; 这里p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3]
表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。
这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。
比如要表示数组中i行j列一个元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
优先级:()>[]>*
数组指针分析:在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。
c语言中数组,指针数组,数组指针,二维数组指针
1.数组和指针
int array[5] = {1,2,3,4,5};// 定义数组
// 1. 指针和数组的关系
int * pa = array;
pa = array;
// p[0] == *(p+0) == array[0] == *(array+0)
printf("%p\n", pa);
printf("%p\n", array);
/*
访问数组两种方式
1. 下标法访问 数组名[下标] 指针[下标] 下标:偏移量
2. 指针法访问 *(p+1)
*/
2.指针数组
int array[5] = {1,2,3,4,5};// 定义数组
int (*p)[5] = &array;// 定义数组指针
int *arr[5];//指针数组,数组中所以得元素保留的是int指针的位置
*p = p[0];
(*p)[1] == array[1];
p[0][1] == (*p)[1] == array[1];
3.二维数组指针
// 3 二维数组的指针
int array2[2][3] = {{1,2,3},{4,5,6}};
int (*p2)[2][3] = NULL;
p2 = &array2;// 把数组赋值给数组指针
*p == array2;
(*p)[0][0] == p[0][0][0];
// /**
// p + 1 跨过6*4 个字节
// p[0] + 1 跨过3*4个字节
// p[0][0] + 1 跨过4个字节
// p[0][0][0] + 1 二维数组第一个元素值+1
// */
4.指针数组
数组中的元素都是指针(地址)
int *arr[5];//指针数组,数组中所以得元素保留的是int指针的位置
int a = 1;
arr[1] = &a;
5.指针的指针
//4.二维指针
int a ;
int *p = &a;
int **pp = &p;// 指针的指针
我们今天的关于PHP行为和数组指针和php行为和数组指针的区别的分享已经告一段落,感谢您的关注,如果您想了解更多关于10、C语言 —— 指针与一维数组(指针数组与数组指针)、c# – 如何编组指向结构数组指针的指针?、C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针、c语言中数组,指针数组,数组指针,二维数组指针的相关信息,请在本站查询。
本文标签: