关于指针的学习

# include <stdio.h>
int main()
{
	int x = 3;
	int* p = &x;          /*星p即是x的指针,又定义了一个p   */
	printf("%p\n", &x);   /*00B3FD58      x的地址*/
	printf("%p\n", &p);   /*00B3FD4C      p的地址      */
	printf("%d\n", x);    /*3*/
	printf("%d\n", *p);   /*3   *p的值就是x   */
	printf("%d\n", &x);   /*11795800   这也是x的地址,只不过是用十进制     */


}

把int看作一个整体,这样后面就是p=&x p是x的地址 ,p就是x的值

# include <stdio.h>
int huhuan(int* p, int* q);
int main()
{
	int a = 3;
	int b = 5;

	huhuan(&a, &b);         /*与下面的函数相对应,int*类型对应&a和&b*/
	printf("a=%d,b=%d\n", a, b);
	return 0;
}
int huhuan(int* p/*a的地址*/, int* q/*b的地址*/)     /*int*类型的要对应&a和&b*/
{
	int t;
	t = *p;        /*不要以为*p就是指针类型了      其实*p是int类型的        *p的值是p中地址所对应的变量值        */
	*p = *q;     /*很重要!!!!!!!!是此程序的关键!!!!!!*p指向a,所对应的存储空间就是a,*p完全就是a,所以在函数中终于找到了a和b*/
	*q = t;        /*这就做到了从函数中搞到了a和b*/
	return 0;
}

此程序用来互换两个数字,用到了函数
假定必须使用函数,那么用传统的方法就不行了,函数内的变量跟外面的没有关系,而且也没法返回两个值,所以必须用到指针

# include <stdio.h>
int f(int* parr, int length);
int main()
{
	int a[5] = { 1,3,5,6,8 };
	f(a, 5);
	return 0;
}
int f(int* parr, int length)     
{
	int i;
	for (i = 0; i < length; i++)
	{
		printf("%d ", *(parr + i));     /*parr中储存了a[0]的地址,所以parr+i代表了数组中其余元素的地址,因为数组中每一个元素的地址是连在一块的*/
		                                /*所以*p(parr+i)能输出数组中所有元素*/
	}
	return 0;
}
# include <stdio.h>
int main()
{
	int a[5];/*a是数组名,5是元素的个数,元素就是变量*/
	int b[5];
	/*a=b error a是常量不能变*/
	printf("%#x\n", &a[0]);
	printf("%#x\n", a);     /*一维数组名是个指针常量,不需要再用取地址符号了*/
	return 0;
}

输出结果是:
0x92fdf8
0x92fdf8
总结:一维数组名是个指针常量,它存放的是一维数组第一个元素的地址

# include <stdio.h>
int f(int* parr, int length);
int main()
{
	int a[5] = { 1,5,6,7,8 };
	printf("%d\n", a[3]);
	f(a, 5);
	printf("%d\n", a[3]);
	return 0;
}
int f(int* parr, int length)      /*为什么要这么麻烦要用指针,还是跟前面一样,在函数内如果不用指针,
								  函数内定义的就算是和main函数里的一样,它们的值也一点关系都没有,所以要用到指针才能把函数内的值搞到外去*/
{
	parr[3] = 88;     /*等价于   *(parr+3)  */
	return 0;
}

要时刻记住a是一个指针变量,它表示&a[0]也就是a[0]的地址

传统数组(静态数组)的缺点:

1.数组长度必须事先制定,且只能是常数,不能是变量;

2.传统数组的内存程序员无法手动释放;

3.传统数组长度一旦定义,其长度就不能再更改;

4.A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行完毕以后,A函数中的数组将无法在被其他函数使用;----------传统方式定义的数组不能跨函数使用;

malloc函数的使用

# include <stdio.h>
# include <malloc.h>  /*不能省*/
int main ()
{ 
   int i = 5;
   int* p=(int*)malloc(4);
    /*1.要使用malloc必须加入头文件
      2.malloc只有一个形参,并且此形参必须是整数
      3.4表示为本程序分配4个字节
      4.malloc函数只能返回第一个字节的地址
    */
    return 0;
}

int*占4个字节,如果malloc(100)那么就会分配25个变量空间

char*占1个字节,如果malloc(100)那么就会分配100个变量空间

double*占8个字节,如果malloc(200)那么就会分配25个变量空间

malloc与函数结合 free函数的使用

# include <stdio.h>
# include <malloc.h>
int main ()
{
    int* p=(int*)malloc(sizeof(int));  /*sizeof(int)的返回值是int类型所占的字节数*/
    *p=10;
    printf("%d ",*p);   /*输出10 */
    f(p);
    printf("%d ",*p);    /*输出200*/
    return 0;
}
int f (*q)
{
    *q=200;
    /*free (q);必须把这一句注释掉,否则的话最后的输出就会有问题,
      free是把q所指向的内容释放掉;
    */
}
# include <stdio.h>
int main ()
{
    /*int a[5]如果int占4个字节,那本数组总共占20个字节,每4个字节被当作一个int类型来使用*/
    int len;
    int* pArr;
    
    printf("请输入你要存放的元素的个数:");
    scanf("%d ",&len);
    pArr = (int*)malloc(4 * len);      /*相当于int a[len];  pArr[0],pArr[1],pArr[...]  */   
    
    return 0;
}

此处直接把前四个格子放在一起,pArr+1就是第5678格子的总称地址,*(pArr+1)就是5678格子内容;

# include <stdio.h>
# include <malloc.h>
int main ()
{
    int i,len,pArr;
    //动态的构造一维数组;
    printf("请输入你要存放元素的个数:");
    scanf("%d",&len);
    pArr = (int*)malloc(4 * len);
    
    //对一维数组进行赋值
    for (i=0;i<len;i++)
        scanf("%d",&pArr[i]); /*pArr[i]===*(pArr+i)   so &pArr[i]====&*(pArr+i)=====pArr+i 这是个地址就对了*/
    
    //对一维数组输出
    printf("一维数组的内容是:\n");
    for (i=0;i<len;i++)
        printf("%d ",pArr[i]);
    
    free (pArr);//释放动态分配的内存
    
    return 0;
}
posted @ 2019-11-04 18:46  panghushalu  阅读(178)  评论(0编辑  收藏  举报