C语言: 指针应用练习

        //----  1. 字符指针可以在定义时直接赋值
        //----  2. 指针在使用前必须先初始化
        //----  3. 通过分配内存给指针赋值,此时指针指向所分配的内存的首地址。

                 3.1 申请分配内存后,必须检查是否成功。
                 3.2 指针释放后应该置NULL
        //----  4. 指针的增减是以指针类型的字节长度为单位进行的
        //----  5. 指针与数组

                 5.1 如果int array[3][4],那么array就是一个数组指针,其类型长度为3*4*sizeof(int)=48
                 5.2 数组指针 : int (*arp)[4] 定义了一个数组指针,arp指向一个含4个int元素的一维数组。
                 5.3 指针数组 : int *par[4] 定义了一个有4个元素的指针数组, 每个元素是一个整型类指针。
        //----  6.指针的指针
                 6.1 多重指针定义和赋值
                 6.2 通过分配内存给多重指针赋值
                 6.3 释放多重指针所指内存 : 指针释放后应该置NULL

pointer.c

#include <stdio.h>
#include <stdlib.h>


int main(void)
{
	int i,j,k;
	int m;


	//---- 1. 字符指针可以在定义时直接赋值
	printf("\n\n ----- 1. Char Pointer Initilization -----\n");
	char *pc = "hello world!"; //OK
	printf( "char pointer pc = %s\n", pc);
	int *p = 5;  // WRONG !!!  warning: initialization makes pointer from integer without a cast !!!!
	printf( " p = %p \n", p);  // p = 0x5

	//---- 2. 指针在使用前必须先初始化
	printf("\n\n ----- 2. Pointer before Init is (nil) -----\n");
 	int *pa;
	printf(" int *pa; pointer before init: pa = %p, or the value of pa is %x\n",pa,(unsigned int)pa);
//	*pa = 1; // WRONG!!!  Segmentation fault (core dumped) !!!

	//---- 3. 通过分配内存给指针赋值,此时指针指向所分配的内存的首地址。
	printf("\n\n ----- 3. Pointer and Malloc/Free -----\n");
	pa=(int *)malloc(5*sizeof(int));
	printf("after malloc 5*sizeof(int), pointer values: \n");
	// --- 3.1 申请分配内存后,必须检查是否成功。
	for(i=0;i<5;i++)
		printf("pa[%d]=%d \n",i,pa[i]);
	printf("pa[6] is out of range, however:  ");
	printf("pa[6]=%d \n",pa[6]);

	free(pa);

	//---- 4. 指针的增减是以指针类型的字节长度为单位进行的
	printf("\n\n ----- 4. Pointer Type Size -----\n");
	for(i=0;i<5;i++) {
		printf("pa+%d=%p\n",i,pa+i);
	}
	    /*  --  print result,4bytes for sizeof(int) ----
		pa+0=0x201b420
		pa+1=0x201b424
		pa+2=0x201b428
		pa+3=0x201b42c
		pa+4=0x201b430
	 		       	    */

	//---- 5. 指针与数组
	printf("\n\n ----- 5. Array and Pointer -----\n");
	int array[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	for(i=0;i<3;i++)
		for(j=0;j<4;j++)
			printf("array[%d][%d]=%d\n",i,j,array[i][j]);
	int *parray=array; //!!!! warning: initialization from incompatible pointer type !!!!
 	printf("\nint array[3][4]=...;\n\nint *parray=array; \n");
	printf("WARNING: initialization from incompatible pointer type!!!\n");
	//------5.1 如果int array[3][4],那么array就是一个数组指针,其类型长度为3*4*sizeof(int)=48
	printf("!!! sizeof(array)=%ld  while  sizeof(*parray)=%ld \n\n",sizeof(array),sizeof(*parray));

	parray=(int *)array;
	printf("parray=(int *)array;\n");
	printf("parray[9]=%d = array[2][1]=%d \n", parray[9], array[2][1]);

	//------5.2 数组指针 : int (*arp)[4] 定义了一个数组指针,arp指向一个含4个int元素的一维数组。
	printf("\n\n ----- 5.1 Array Pointer: int (*arp)[]    [ > ( > * -----\n");
	int (*arp)[4];

	arp=array; //或 ap= array[0] 或 ap=&array[0][0];
	for(i=0;i<4;i++)
	{
		printf("(arp+1)[0][%d]=%d\n",i,(arp+1)[0][i]);
		// arp[2][i] 和 (arp+2)[0][i] 相同!
		printf("arp[2][%d]=%d  ",i,arp[2][i]);
		printf("(arp+2)[0][%d]=%d\n",i,(arp+2)[0][i]);
	}

	//------5.3 指针数组 : int *par[4] 定义了一个有4个元素的指针数组, 每个元素是一个整型类指针。
	printf("\n\n ----- 5.2 Pointer Array: int *par[]    [ > ( > * -----\n");

	int *par[3];

	par[0]=(int *)array[0]; //或则 &array[0][0]
	par[1]=(int *)array[1];
	par[2]=(int *)array[2];
	for(i=0;i<3;i++)
	{
		printf("par[%d]=(int *)array[%d];   ",i,i);
		printf(" *par[%d] = %d \n", i,*array[i]); //*array[i] 和 array[i][0] 相等*/
	}

	//----- 6.指针的指针
	printf("\n\n ----- 6. Pointer to Pointer  -----\n");
	//-------6.1 多重指针定义和赋值
	int var=666;
	int *ptr;
	int **pptr;

	printf("\n\n ----- 6.2 Pointer to Pointer: Assignment -----\n");
	printf("var=%d\n",var);
//	pptr=&(&var); // !!! WRONG !!! & must follows with a variable name.
	ptr=&var;
	printf("ptr=&var=%p\n",ptr);
	pptr=&ptr;
	printf("pptr=&ptr=%p\n",pptr);

	printf("\npptr[0] = %p\n", pptr[0]);
	printf("pptr[0][0] = %d\n", pptr[0][0]);

	//-------6.2 通过分配内存给多重指针赋值
	printf("\n\n ----- 6.2 Pointer to Pointer:  Malloc and Free -----\n");

	int *** ppptr;  //[3][2][2]
	//	ppptr ----> (int **)  ----> (int *) ----> (int)
	//		|	       |	     |
	//		|	       |	     |--> (int)
	//		|	       |-> (int *)
	//		|
	//		|--> (int **)  --
	//		|
	//		|--> (int **)  --


for(m=0;m<50000;m++)  //-------------   check memory leakage  ----------
{
	//----- malloc for ppptr : pointer to  (int **)
	ppptr=malloc(3*sizeof(int **));
	printf("ppptr=malloc(3*sizeof(int **))=%p\n", ppptr);

	for(i=0;i<3;i++) {
		//----- malloc for (* ppptr) :  pointer to (int *)
		ppptr[i]=malloc(2*sizeof(int *));
		printf("*ppptr: ppptr[%d]=%p \n",i,ppptr[i]);
		for(j=0;j<2;j++) {
			//----- malloc for (** ppptr) :  pointer to (int)
			ppptr[i][j]=malloc(2*sizeof(int));
			printf("**ppptr: ppptr[%d][%d]=%p \n",i,j,ppptr[i][j]);
		}
	}

	ppptr[2][1][0]=88888;
	printf("ppptr[2][1][0]=88888 \n");
	for(i=0;i<3;i++)
		for(j=0;j<2;j++)
			for(k=0;k<2;k++)
				printf("***ppptr: ppptr[%d][%d][%d]=%d \n",i,j,k,ppptr[i][j][k]);

//} //---END  test leakage

	//-------6.3 释放多重指针所指内存 : 指针释放后应该置NULL
	printf("\n\n ----- 6.3 Free Pointer to Pointer  -----\n");
	for(i=0;i<3;i++) {
		for(j=0;j<2;j++) {
			free(ppptr[i][j]);	//---free:  ppptr[i][j]=malloc(2*sizeof(int));
			ppptr[i][j]=NULL;
			//printf("ppptr[%d][%d][0] = %d\n",i,j,ppptr[i][j][0]);
			printf("ppptr[%d][%d] = %p\n",i,j,ppptr[i][j]);
			if(j == 2-1){
				free(ppptr[i]);   //---free:  ppptr[i]=malloc(2*sizeof(int *));
				ppptr[i]=NULL;
				printf("ppptr[%d] = %p\n",i,ppptr[i]);
			}
		}
	}

	free(ppptr);	//---free:   ppptr=malloc(3*sizeof(int **));
	ppptr=NULL;
	printf("ppptr = %p\n",ppptr);


 }  //---END check leakage

	return 0;
}


/*
					--- mem result ---

 ----- 6.2 Pointer to Pointer and Malloc/Free -----
ppptr=malloc(3*sizeof(int **))=0xaec420
*ppptr: ppptr[0]=0xaec440
**ppptr: ppptr[0][0]=0xaec460
**ppptr: ppptr[0][1]=0xaec480
*ppptr: ppptr[1]=0xaec4a0
**ppptr: ppptr[1][0]=0xaec4c0
**ppptr: ppptr[1][1]=0xaec4e0
*ppptr: ppptr[2]=0xaec500
**ppptr: ppptr[2][0]=0xaec520
**ppptr: ppptr[2][1]=0xaec540

					--- proc maps ---

00400000-00402000 r-xp 00000000 08:07 139229                             /home/midas-zhou/pointer
00601000-00602000 r--p 00001000 08:07 139229                             /home/midas-zhou/pointer
00602000-00603000 rw-p 00002000 08:07 139229                             /home/midas-zhou/pointer
00aec000-00b0d000 rw-p 00000000 00:00 0          	 <<<--------     [heap]
7fa6e50d3000-7fa6e5293000 r-xp 00000000 08:08 792498                     /lib/x86_64-linux-gnu/libc-2.23.so
7fa6e5293000-7fa6e5493000 ---p 001c0000 08:08 792498                     /lib/x86_64-linux-gnu/libc-2.23.so
7fa6e5493000-7fa6e5497000 r--p 001c0000 08:08 792498                     /lib/x86_64-linux-gnu/libc-2.23.so
7fa6e5497000-7fa6e5499000 rw-p 001c4000 08:08 792498                     /lib/x86_64-linux-gnu/libc-2.23.so
7fa6e5499000-7fa6e549d000 rw-p 00000000 00:00 0
7fa6e549d000-7fa6e54c3000 r-xp 00000000 08:08 792470                     /lib/x86_64-linux-gnu/ld-2.23.so
7fa6e56a3000-7fa6e56a6000 rw-p 00000000 00:00 0
7fa6e56c2000-7fa6e56c3000 r--p 00025000 08:08 792470                     /lib/x86_64-linux-gnu/ld-2.23.so
7fa6e56c3000-7fa6e56c4000 rw-p 00026000 08:08 792470                     /lib/x86_64-linux-gnu/ld-2.23.so
7fa6e56c4000-7fa6e56c5000 rw-p 00000000 00:00 0
7ffc0fc00000-7ffc0fc21000 rw-p 00000000 00:00 0                          [stack]
7ffc0fd7a000-7ffc0fd7d000 r--p 00000000 00:00 0                          [vvar]
7ffc0fd7d000-7ffc0fd7f000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


				---  Leakage Test ----
VIRT: virtual memory
RES: physical memory
( top -d 1 )
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
29063 midas-z+  20   0    4356    728    660 R  39.2  0.0   0:07.99 pointer


*/


 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Midas-Zhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值