指针数组与数组指针

本文详细探讨了指针与数组的基础概念,包括它们的定义、操作、数组名的特性,以及指针数组和数组指针的区别。重点讲解了为何两者虽然相似,但实质上是不同的数据结构。通过实例演示,展示了指针在内存地址操作中的关键作用以及在数组操作中的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、指针与数组

指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。总的来说指针就是变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)

int main()
{
    int a = 10;    //在内存中开辟一块空间
    int *p = &a;   //这里我们对变量a,取出它的地址,可以使用&操作符
                   //将a的地址存放在p变量中,p就是一个指针变量
    printf("%p\n",&a);
    printf("%p\n",p);    //打印变量a的地址
         
    return 0;
}

数组名的值是一个指针常量,也就是数组首元素的地址。

以下两种情况中,数组名不表示首元素地址: 

1、sizeof(数组名),计算整个数组的长度,单位是字节,数组名表示整个数组。
2、&数组名,所产生的是一个指向数组的指针,取出的是整个数组的地址。数组名表示整个数组。

由于数组名的值是一个指针常量,可以采用间接访问操作符 '*' 访问指针指向的内容,*arr即可访问数组首元素。

arr == &arr[0];
*arr == arr[0];

下面这条赋值语句,将arr的值,即首元素地址赋给指针变量p。

int *p = arr; 

 p所指向的是数组的首元素,p和arr都可以进行间接访问和下标引用操作,下列四种访问方法等价:

*(p+i) == *(arr+i) == p[i] == arr[i]

 下面程序依次打印数组各个元素,其中四条打印语句表达的意思相同。

int main()
{
	int arr[5] = { 1,2,3,4,5};
	int *p = arr;              
	int i;
	for (i = 0; i < 5; i++)
	{
		printf("%d\n", *(p+i));      
		printf("%d\n", *(arr+i)); 
        printf("%d\n",  p[i]);                       
		printf("%d\n", arr[i]);
	}

	return 0;
}

但是!!!

请不要根据这个事实得出“数组和指针是相同的”结论!!!

现考虑以下声明:

int arr[5];
int *p ;

声明一个数组时,编译器会根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值是一个常量,指向这段空间的起始位置。声明一个指针变量时,编译器只为指针本身保留内存空间,它并不为任何整型值分配内存空间。此外,指针变量未被初始化为指向任何现有的内存空间,如果它是一个自动变量,它甚至根本不会被初始化。把这两个声明用图的方法来表示,可以发现他们的显著不同。

因此,上述声明之后,表达式*arr是完全合法的,但表达式*b是非法的,*b将访问内存中某个不确定的位置,或者导致程序终止。另外,表达式b++可以通过编译,但arr++不行,因为arr的值是个指针常量,常量的值是不能被修改的。(--------指针常量所指向的是内存中数组的起始位置,如果修改这个指针常量,唯一可行的操作就是把整个数组移动到内存的其他位置。但是,在程序完成链接之后,内存中数组的位置是固定的,因此,数组名的值是一个指针常量。)

二、指针数组

指针数组是数组,是存放指针的数组。

以下声明表示:arr是一个数组,有五个元素,每个元素是一个整形指针。

int* arr[5];        //指针数组

 下面这个程序依次打印三个整型数组的值。

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	Int *parr[] = { arr1,arr2,arr3 };
	int i = 0;
	for ( i = 0; i < 3	; i++)
	{
		int j = 0;
		for ( j = 0; j < 5; j++)
		{
			printf("%d", *(parr[i] + j));
		}
		printf("\n");
	}
	return 0;
}

注意:指针数组以一个NULL指针结束

三、数组指针

数组指针是指针,是指向数组的指针。

以下声明表示,p是一个指针,它指向的数组有五个元素,每个元素的类型是整型。

int (*p)[5];        //数组指针

同理,以下声明表示,p是一个指针,它指向的数组有十个元素,每个元素的类型是字符指针。

char* (*p)[10];    

(注意:指针数组和数组指针的声明相差只相差一个 () ,由于 [ ] 的优先级要高于 * ,arr先和 [ ] 结合,说明arr是一个数组;但加上 () 后,保证 * 与 p 先结合,则说明 p 是指针。)

数组指针的声明和初始化一般如下:

int arr[10] = { 0 };
int (*p)[10] = &arr;

数组指针是个指向数组的指针,因此也可以进行间接访问和下标引用操作。

*p 就是arr

(*p)[i] == arr[i] == *(*p+i) == *(arr+i)

下面程序任然是依次打印数组各个元素

int main()
{
	int arr[5] = {1,2,3,4,5};
	int (*p)[5] = &arr;               
	int i = 0;
	for ( i = 0; i < 5; i++)
	{
		printf("%d\n", (*p)[i]);  
        printf("%d\n", arr[i]);  
        printf("%d\n", *(*p+i));  
        printf("%d\n", *(arr+i));  
	}
	 
	return 0;
}

对比以前的程序,这个程序明显更加复杂。

一般数组指针用在多维数组更方便。

下面程序是一个打印二维数组各个元素的程序,依旧采用四种等价写法:

void print(int (*p)[5], int x, int y)      //需要用数组指针接收
{
	int i = 0, j = 0;
	for ( i = 0; i < x; i++)
	{
		for ( j = 0; j < y; j++)
		{
			printf("%d ",p[i][j]);          
			printf("%d ",*(p[i]+j));
			printf("%d ",(*(p+i)[j]);
			printf("%d ", *(*(p+i) + j));   
        }                                                     
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
	print(arr, 3, 5);    //arr的值是首元素地址, 二维数组中 ,首元素地址为第一行地址
	return 0;
}

内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值