C语言基础知识之数组指针和指针数组

指针和数组的区别

         首先我们编写如下代码:

	#include<stdio.h>
	#include<stdlib.h>
	 
	int main(){
		char *s1 = "hello";
		char *s2 = "hello";
		char a1[] = "hello";
		char a2[] = "hello";
		printf("%p %p %p %p \n",s1, s2, a1, a2);
		return 0;
	}

         程序运行结果:
数组和指针运行结果
         从结果可以看出,第一个和第二个 “hello” 的地址都为 “0000000000404000” ,原因是这个时候的数指针指向的 “hello” 为字符串常量,它存放在静态存储区(静态存储区的特点是,内存从分配之后一直到程序结束才会被回收),因此,对于两个 “hello” 这样的字符串常量它的值是一样的,所以 s1、s2 实际指向的是同一个 “hello” ,因此看到的地址是相同的;对于 a1、a2 而言,它们是局部变量,放在上,栈上的内容是可以随时修改的,它们是指向两个不同的 “hello” ,它的值可以改为其它内容,因此这里一共有 3 个 “hello”。

	*s1 = ‘H’;  // 错误,*s1 为字符串常量,不可以修改
	*a1 = ‘H’; // 正确,a1[]为局部变量,可以修改
	s1++;       // 正确,s1 是地址变量,可以修改
	a1++;       // 错误,a1 是地址常量,不可以修改


	char* get_string(){
		char *s = "hello";   // 正确, 字符串常量在静态存储区,程序结束时才会回收内存地址
		char s[] = “hello”;  // 错误,局部变量在栈上,相应程序结束后该内存地址不能使用
		return s;
	}

0 指针数组

         指针数组是数组,数组的每一个元素是指针,形式如下:

	<数据类型> *<指针变量名>[<大小>];

         指针数组名表示该指针数组的起始地址。
代码写法如下:

	int main(){
		int a=1, b=2,  c=3;
		int* p[3] = {&a, &b, &c};
		return  0;
	}

         或

	typedef int* ptype[3];
	int main(){
		int a=5,  b=2,  c=0;
		ptype p =  {&a, &b, &c};
		return  0;
	}

例0.0 编程实现通过指针数组来遍历二维数组

	#include<stdio.h>
	
	int main(){
		int a[2][3]  = {{1,3,5}, {1,9,6}};
		int *p[2];
		int i, j;
		
		p[0] = a[0];
		p[1] = a[1];
		
		for(i=0; i<2; i++){
			for(j=0; j<3; j++){
				printf("%d ", *(p[i]+j)); //p[i][j]
			}
			puts("");
		}
		return 0;
	}

         运行结果
Result_0_0
         Q1:指针数组占空间大小?
         A1: sizeof(数据类型)*数组长度。
         Q2: 指针数组是什么样的指针?
         A2: 二级指针。
         Q3: 指针数组名加 1 移动多少字节?
         A3:sizeof(数据类型)。

1 数组指针

         数组指针式指针,指向数组的指针,也就是指向数组首地址的地址,形式如下,

	<数据类型> (*<指针变量名>)[表达式];

         代码写法如下:

	int main(){
		int a=  {123};
		int*p)[3] = &a;
		return  0;
	}

        或

	typedef int*ptype)[3];
	int main(){
		int a=  {123};
		ptype p =  &a;
		return  0;
	}

例1.0

	int a[3][3], (*p)[3];
	p =  a;
	下面表示 a 数组元素的是哪一个选项()
	A:p+1		B:*(p+1)	C:*(p+1)+1	D:*(*p+1)

        解析: 二维数组名代(a)表数组的起始地址,数组名加 1 (a+1),移动 1 行元素。p+1 等价于 p[1]或a[1]的 地址 , *(p+1)等价于 p[1]或a[1],*(p+1)+1等价于 p[1][1] 的地址,*(*p+1)等价于 p[0][1]、a[0][1]。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值