c指针

来源:互联网 发布:淘宝宝贝详情图尺寸 编辑:程序博客网 时间:2024/06/07 23:17

char *ptr

定一个指针,没有赋值,用NULL

char *ptr = NULL 即表示指向空,不能再做赋值,不能对0地址操作访问。

 

//#define NULL void *o

如果出现段错误,看看对NULL有没有赋值。

 

如何避免野指针而不是杜绝:

1.如果没有对指针进行赋值,可把指针指向空,可避免野指针

2.如果出现段错误,可查看有没有对NULL进行赋值

3.当你要把指针指向的空间赋值时,应先分配一下空间

 

char *ptr=hello world

*ptr=L

不对,会出现段错误,ptr是个常量,没有办法赋值。

 

ptr=char *malloc100*sizeofchar);蓝色部分是为了增加可移植性

指针必须是相同类型赋值,如果不是相同类型1.会越界2.取数据不完整

 

void*:称为万能指针

缺点:不能作取值操作

 

 

 

二:获取字符串的两种方法。以及malloccallocralloc的使用注意点

获取字符串两种方法

1.char ptr[100];

  1#include<stdio.h>

  2 #include<stdlib.h>

  3 #define MAX_SIZE 1024

  4 int main()

  5 {

  6     char *ptr=(char *)malloc(MAX_SIZE*sizeof(char));   malloc分配内存空间。

  7     if(NULL==ptr)

  8     {

  9         printf("malloc error!\n");         看内存是否分配成功。

 10         exit(1);

 11     }

 12         //memset(ptr,'\0',sizeof(ptr));     其中‘\0’是表示拿0来填充这100个字节。

 13         memset(ptr,'\0',sizeof(char)*MAX_SIZE);    指把空间全部清空。

 14         //bzero(ptr,MAX_SIZE)

 15         scanf("%s",ptr);

 16         printf("ptr=%s\n",ptr);

17         free(ptr);     释放空间。释放以后,ptr没值了,但是还保存了原来的地址,      如果不置为空,会变成野指针

 18         ptr=NULL;

 19         return 0;

 20 }

malloc的头文件#include<stdlib.h>

 

用了空间再用一次的时候一定要记得清空

 

通常都是先分配空间,然后检验空间是否分配成功,把空间里面的残留元素都清空,然后初始化,再释放,最后再初始化。

通常用memset来初始化一块内存。

 

 

mallocrelloccalloc的区别。

char *ptr=(char *)malloc(MAX_SIZE*sizeof(char));

char *ptr=(char *)calloc(20,sizeof(char));

 

1. malloc不能初始化所分配的内存空间,而函数calloc能。如果malloc函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配过,则其中可能遗留各种各样的数据,也就是说,使用malloc函数的程序开始时(内存还没有被重新分配)能正常进行,但经过一段时间(内存已经被重新分配,可能会出现一些问题)。

2. calloc会将所分配的空间中的每一位都初始化为零,也就是说如果你是字符类型或整数类型的元素分配内存,那么这些元素将保证会被动的初始化为0,如果你为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针。如果你为实型元素分配内存,则这些元素会被初始化为浮点型的0。

3. realloc可以对给定的指针所指向的空间进行扩大或缩小,无论是扩大还是缩小,原有的内存中的内容将保持不变对于缩小,则被缩小的那一部分的内容将会丢失,realloc并不保持调整后的内存空间和原来的 内存空间保持同一内存地址,realloc返回的指针很可能指向新的地址。

 

实现原理

malloc、calloc函数的实质体现在,它有一个将可用的内存连接为一个长长的链表(即所谓的空闲链表)。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块,然后将该内存块一分为二(一块的大小与用户申请的大小一样,另一块就是剩下的字节),接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话),返回到链表上,调用free函数 时,它将用户释放的内存块连接到空链上,到最后,空闲链表会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可能满足用户要求的片段了,于是malloc函数请求延时,并开始在空间中翻箱倒柜的检查内存片段,对它们进行整理,并将相邻的小空闲块合成较大的内存块

 

三.指针转换的表现形式以及二维数组三维数组的详解

指针+整数:加步长

指针+指针:指两个地址之间相差的数据类型的个数

 

  1#include<stdio.h>

  2 #define MAX_SIZE 3

  3 int main()

  4 {

  5     int a[MAX_SIZE]={0};

  6     int *p=a;

  7     scanf("%d",&a[i]);

  8     scanf("%d",a+i);

  9     scanf("%d",p+i);

 10     scanf("%d",p);

 11     scanf("%d",p++);

 12     scanf("%d",&p[i]);

 13     scanf("%d",a++);error 错的因为a是数组的首地址,没有办法自加。

         指针常量,保存的是数组a的首地址。

 14     p=a;

 15     for(i = 0; i < MAX_SIZE; i++)

 16     printf("a[%d]=%d\n",a[i]);

 17     printf("a[%d]=%d\n",p[i]);

 18     printf("a[%d]=%d\n",*(p+i));

 19     printf("a[%d]=%d\n",*(a+i));

 20     printf("a[%d]=%d\n",*(p++));

 21     printf("a[%d]=%d\n",)

 22 }

 

 

对数组地址取值:为数组首元素的地址

对数组名取地址:为数组的地址

变量存数,指针变量存的是地址

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

数组指针:a pointer to an array,即指向数组的指针

函数指针:保存的函数地址

总之一句话,定义了指针一定要知道指针指向哪里,不然要悲剧。

                       

二维数组可以省略列不可以省略行

 

 

二维数组名,a代表首个一维数组的地址。

二维数组的单位是一个一维数组。

scanf("%d",&a[i][j]);

printf("a[%d][%d]"=%d\n",i,j,a[i][j]);

scanf("%d",*(a+i)+j);

printf("a[%d][%d]"=%d\n",i,j,*(*(a+i)+j));

*(*(a+i)+j):

a+i:第i+1个一维数组的地址。

*(a+i):第i+1个一维数组首元素的地址

*(a+i)+j:第i+1个一维数组第j+1个元素的地址

*(*(a+i)+j):第i+1个一维数组第j+1个元素的值

 

三维数组:a代表首个二维数组的地址

*(&a)=a:为首个一维数组的地址

 

*(*(*(a+i)+j)+k)

a+i:第i+1个二维数组的地址。

*(a+i):第i+1个二维数组的第一个一维数组的地址

*(a+i)+j:第i+1个二维数组的第j+1个一维数组的地址

*(*(a+i)+j):第i+1个二维数组第j+1个一维数组的首元素的地址

*(*(a+i)+j)+k:第i+1个二维数组第j+1个一维数组第k+1个元素的地址

*(*(*(a+i)+j)+k):第i+1个二维数组第j+1个一维数组第k+1个元素的值

 

sizeof里面存放的是字节

[]=*()

 

四.

函数中传送和接受的对应

1传一维数组名,用元素指针来接

2传二维数组名,用一维数组指针来接

3传三维数组名,用二维数组指针来接

4.指针数组,用指针的指针来接。

void print_src(char(*src)[100])

void print_ktc(char(*ktr)[3][100])

指针就是间接性的访问。

1 0
原创粉丝点击