8.指针和(数组、函数)

【指针和数组】
      指针和一维数组
               数组名
               int a[5];//a是数组名,5是数组元素的个数,元素就是变量

               int a[3][4];//3行4列,a[0][0]是第一个元素,a[i][j]实际表示第i+1行第j+1列,即4行5列

               如果是实际的二维数组赋值,例如:a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}

               而在这个数组中第十二个数字23的真实位置如果按以下方式来排列:

               a[0][0]、a[0][1]、a[0][2]、a[0][3]

               a[1][0]、a[1][1]、a[1][2]、a[1][3]

               a[2][0]、a[2][1]、a[2][2]、a[2][3]

               则是a[3-1][4-1] == a[2][3]  也就是在第二行第三列,注意不要弄混淆了。

               int b[5];
               a = b; //erroe 因为a是常量
               printf("%#x",&a[0]); 以16进制输出第一个元素a[0]的地址
               printf("%#x",a);和printf("%#x",&a[0]);输出的结果是一样的,都为0X12FF6C
-----------------------------------------------------------------------
一维数组名是个指针常量,它存放的是一维数组第一个元素的地址
------------------------------------------------------------------------------------------
下标和指针的关系:
       如果p是个指针变量,则
       p[i]永远等价于*(p+i)
             [确定一个一维数组需要几个参数]
             [如果一个函数要处理一个一维数组,则需要接受该数组的哪些信息]
如下面的例子所示:需要两个参数:
             数组的第一个元素的地址
             数组的长度
--------------------------------------------------------------------
				#include <stdio.h>
				//f函数可以输出任何一个一维数组的内容
				void f(int *pArr, int len)    //这里的len表示数组的长度 
				{
					int i;
					for (i=0;i<len,++i)        //*pArr = *(pArr+i)
						printf("%d",*(pArr+i));  // *pArr *(pArr+1) *(pArr+2) *(pArr+3)
					printf("\n");
				}
				int main(void)
				{
					int a[5] = {1,2,3,4,5};
					int b[6] = {-1,-2,-3,4,5,-6}
					int c[100] = {1,99,22,33};

					f(a,5);   //a是int *   且 a 等同于 &a[0]
					f(b,6);
					f(c,100);
					
					return 0;
				}
				---------------------------------------------
				#include <stdio.h>
				void f(int * pArr, int len)
				{
					pArr[3] = 88;   //pArr[3]等价于*(pArr+3)
				}
				int main(void)
				{
					int a[6] = {1,2,3,4,5,6};
					printf("%d\n",a[3]);   //输出的结果是4
					f(a,6);
					printf("%d\n",a[3]);   //输出的结果是88
					return 0;      
				}

注释:

         *pArr = *(pArr+i)         

         *pArr *(pArr+1) *(pArr+2) *(pArr+3)

         因为f(a,6);中a指向的是a[0],值为1,那么传递给pArr以后,pArr也是指向的a[0],值也为1
         又因为p[i]永远等价于*(p+i)即pArr[3]等价于*(pArr+3)即*(0+3)所以pArr[3]就相当于指向a[3]
         而pArr[3] = 88;就等于是给a[3]进行了重新赋值88,所以最后a[3]的值为88

         pArr[3] = 88;和printf("%d\n",a[3]);中的pArr[3]和a[3]是同一个变量
				------------------------------------------------------------------------------------------	
				#include <stdio.h>
				void f(int * pArr, int len)
				{
					pArr[2] = 10;          //pArr[2] == *(a+2) == a[2]
				}
				int main(void)
				{
					int a[5] = {1,2,3,4,5}

					printf("%d\n",a[2]);
					f(a,5);
					printf("%d\n",a[2]);
				//	a = &a[2];     //error 因为a是常量
				//	printf("%#X, %#X\n",a,&a[0]);
				//	a == &a[0]
					return 0;
				}
				------输出结果为2和10-------------------------------------------
指针变量的运算
        指针变量不能相加 不能相乘 也不能相除 只能相减
        如果两个指针变量指向的是同一块连续空间中的不同存储单元
        则这两个指针变量才可以相减
					------------------------------------
					#include <stdio.h>
					int main(void)
					{
						int i = 5;
						int j = 10;
						int * p = &i;
						int * q = &j;
						int a[5];
						p = &a[1];
						q = &a[4];
						printf("p和q所指向的单元相隔%d个单元\n",p-q);   //并没有实际的意义
						return 0;
					}
					------输出结果为:p和q所指向的单元相隔3个单元--------------------------
一个指针变量到底占用几个字节
    预备知识:
            sizeof(数据类型)
                 功能:返回值就是该数据类型所占的字节数
                 例子:sizeof(int) = 4 sizeof(char) = 1 sizeof(double) = 8

    sizeof(变量名)
            功能:返回值是该变量所占字节数

            假设p指向char类型变量(1个字节)
            假设p指向int类型变量(4个字节)
            假设p指向double类型变量(8个字节)
            p q r本身所占的字节数是一样的

总结:
         一个指针变量,无论它指向的变量占几个字节,该指针变量本身只占4个字节
         一个变量的地址使用该变量首字节的地址来表示
					-------------------------------------------------------------------------
					#include <stdio.h>
					int main(void)
					{
						char ch = 'A';
						int i = 99;
						double x = 66.6;
						char * p = &ch;
						int * q = &i;
						double * r = &x;
						printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r));
						return 0;
					}
					------输出结果为:4 4 4---------------------------------------
详解:
         硬件内存为一个单元是一个字节,一个字节是8bit,而又一个字节是一个地址编号
         而x理论占8个字节,即x有8个地址编号,那么取x地址的时候到底是取的8个字节中即8个编号中哪一个来
         作为x的编号呢?而最终规定使用 第一个字节的地址当做x的地址编号
          而最终无论是保留首地址还是末地址作为x的地址编号,他们都占4个字节即4*8=32bit,32也是cpu的线程总线数
        【2的32次方=4G RAM】 cpu的2的32次方个状态,所以对应地址编号都按照32bit来进行存储,所以无论是哪个编号
         它最终都只占4个字节。所以输出的结果为4 4 4

【指针和函数】

			----------------------------
			#include <stdio.h>
			void g(int **q)        
			{
        		**q = 20;     //*q 就是p
			}
			int main(void)
			{
        		int i=1;
        		int *p=&i;
        		g(&p);         //p是int*类型,&p是int**类型
        		printf("i = %d\n",i);
        		return 0;
			}
			程序的运行结果是:i = 20
			---------------------------------------------------

【多级指针】

			-------------------------
			#include <stdio.h>
			int main(void)
			{
				int i = 10;
				int *p = &i;
				int **q = &p;
				int ***r = &q;
				//r=&p; error,因为r是int***类型,r只能存放int**类型变量
				printf("i = %d\n",***r);
				return 0;	
			}
			程序运行结果为i=10

			----------------------------------------------------------------------------------------
                                        解析:
                                                int i = 10 = *P = *(int i) = *q = *[*(int i)] = *r = *{*[*(int i)]}
                                               所以最终 ***r = i;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值