GVKun编程网logo

PHP行为和数组指针(php行为和数组指针的区别)

11

此处将为大家介绍关于PHP行为和数组指针的详细内容,并且为您解答有关php行为和数组指针的区别的相关问题,此外,我们还将为您介绍关于10、C语言——指针与一维数组(指针数组与数组指针)、c#–如何编组

此处将为大家介绍关于PHP行为和数组指针的详细内容,并且为您解答有关php行为和数组指针的区别的相关问题,此外,我们还将为您介绍关于10、C语言 —— 指针与一维数组(指针数组与数组指针)、c# – 如何编组指向结构数组指针的指针?、C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针、c语言中数组,指针数组,数组指针,二维数组指针的有用信息。

本文目录一览:

PHP行为和数组指针(php行为和数组指针的区别)

PHP行为和数组指针(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语言 —— 指针与一维数组(指针数组与数组指针)

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# – 如何编组指向结构数组指针的指针?

c# – 如何编组指向结构数组指针的指针?

我的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 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针

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语言中数组,指针数组,数组指针,二维数组指针

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语言中数组,指针数组,数组指针,二维数组指针的相关信息,请在本站查询。

本文标签: