指针1

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

    void pointer_access()

    {

        ///a: 指针访问

        char a[20]= {'s','d','f','g','h','j','k'};

        printf("char_adr_a= %p\n",a);//数组名是首地址.6

        int *ptr=(int *)a; //强制类型转换并不会改变a 的类型.

        printf("int_adr_a= %p\n",a);//转换后, a的地址没发生变化.

 

        printf("a= %c\n",*a);

        ptr++;

        //a++;   //错误操作.

        printf("ptr_adr= %p\n",ptr);

        printf("ptr= %c\n",*ptr);//四个字节作为一个单位.

        printf("a= %c\n",*a);//不会随着ptr 的改变而改变.

        printf("\n\n");

    }

 

    void pointer_array_foreach()

    {

    ///s: (指针+循环)遍历数组.

        int array[10]= {0,1,2,3,4,5,6,7,8,9};

        int *ptr1=array; //等价于: int *ptr1; ptr1=array;//定义一个指针变量,并且指针指向数组a

        int i;

        for(i=0; i<10; i++)

        {

            (*ptr1)++;

            ptr1++;

        }

        for(i=0; i<10; i++)

            printf("array[%d]= %d\n",i,*(ptr1));//用指针取数值 *(array+i)

        printf("\n\n");

    }

 

 

void pointer_access_overflow()

{

    ///d: 指针访问越界

    int i;

    char string[20]="You_are_a_girl";

    int *ptr2=(int *)string;//前后兼容(compatible)

 

    ptr2+=5;//移动了20 个字节

    for(i=0; i<20; i++)

        printf("%c",*(ptr2+i));//*(string)————只输出20Y. 不能用*(ptr2+i),因为 ptr2int.

    printf("\n\n");

    puts(string);

    printf("\n\n");

 

    /*

      将指针ptr2 的值加上5 sizeof(int),在32 位程序中就是加上了5 4=20,

      由于地址的单位是字节,故向高地址方向移动了20 个字节。

      5 后,ptr2 已经指向了数组a 的合法范围之外了。虽然这种情况在应用上会出问题,

      但在语法上却是可以的。*/

}

 

 

void pointer_add()

{

///f: 指针+整数, 指针+指针

 

 

    char aa[20]=" You_are_a_girl";

    char *p=aa;

    char **ptr3=&p;

    printf("p= %d\n",p);

    printf("ptr3= %d\n",ptr3);

    printf("*ptr3= %d\n",*ptr3);

 

 

    ptr3++;

    printf("ptr3= %d\n",ptr3);

    printf("*ptr3= %d\n",*ptr3);

    //printf("**ptr3= %c\n",**ptr3);

    printf("\n\n");

 

 

    /*

    1.一个指针ptrold ()一个整数n 后,结果是一个新的指针ptrnew

    ptrnew 的类型和ptrold 的类型相同,ptrnew 所指向的类型和ptrold所指向的类型也相同。

    ptrnew 的值将比ptrold 的值增加(减少)n sizeof(ptrold 所指向的类型)个字节。

    就是说,ptrnew 所指向的内存区将比ptrold 所指向的内存区向高()地址方向移动了n sizeof(ptrold 所指向的类型)个字节。

 

    2.指针和指针进行加减:两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,

    而且毫无意义.两个指针可以进行减法操作,但必须类型相同,一般用在数组方面,不多说了。*/

}

void pointer_expression()

{

///h: 指针表达式

    int a2,b2;

    int array1[10];

    int *pa;

    pa=&a2; //&a2 是一个指针表达式。

    int **ptr5=&pa; //&pa 也是一个指针表达式。

    *ptr5=&b2; //*ptr5 &b2 都是指针表达式。

    pa=array1;

    pa++; //这也是指针表达式。

 

 

    char *arr[20];

    char **parr=arr; //如果把arr 看作指针的话,arr 也是指针表达式

    char *str;

    str=*parr; //*parr 是指针表达式

    str=*(parr+1); //*(parr+1)是指针表达式

    str=*(parr+2); //*(parr+2)是指针表达式

}

 

 

void pointer_operator()

{

 

 

///g: 运算符&*.

    int a1=12;

    int b1=36;

    int *p1;    //p1 是一个指针,指针所指向的内容的类型为int . 指针的类型是int*,

                //所以p1是一个返回整型数据的指针.

    

    p1=&a1;     //&a1 的结果是一个指针,类型是int*,指向的类型是

                //int,指向的地址是a1 的地址。

    *p1=24;     //*p1 的结果,在这里它的类型是int,它所占用的地址是

                //p1 所指向的地址 ,显然,*p1 就是变量a

    printf("*p1= %d\n",*p1);

    printf("p1_adr= %p",&(*p1));

    printf("\n\n");

 

    int **ptr4;

    ptr4=&p1;   //&p1 的结果是个指针,该指针的类型是p1 的类型加个*

                //在这里是int **。该指针所指向的类型是p1 的类型,这

                //里是int*。该指针所指向的地址就是指针p1 自己的地址。

    *ptr4=&b1;   //*ptr4 是个指针,&b1 的结果也是个指针,且这两个指针

                //的类型和所指向的类型是一样的,所以用&b1 来给*ptr4

                //值就是毫无问题的了。

    printf("**ptr4= %d\n",**ptr4);

    printf("**ptr4_adr= %p",&(**ptr4));

    printf("\n\n");

 

 

    **ptr4=48; //*ptr4 的结果是ptr4 所指向的东西,在这里是一个指针,

               //对这个指针再做一次*运算,结果是一个int 类型的变量。

    printf("**ptr4= %d\n",**ptr4);

    printf("**ptr4_adr= %p",&(**ptr4));

    printf("\n\n");

}

 

void pointer_array()

{

    char *str[3]= {"Hello,thisisasample!","Hi,goodmorning.","Helloworld"};

    char s1[80],s2[80];

    //strcpy(s,str[0]);  //也可写成strcpy(s,*str);

    strcpy(s1,str[1]);   //也可写成strcpy(s,*(str+1));

    strcpy(s2,*(str+1));

    puts(s1);

    puts(s2);

    printf("\n\n");

 

    /*str 是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。

    (1)把指针数组名str 当作一个指针的话,它指向数组的第0 号单元,它的类型是char **,它指向的类型是char *

    (2)*str 也是一个指针,它的类型是char *,它所指向的类型是char

    它指向的地址是字符串"Hello,thisisasample!"的第一个字符的地址,即'H'的地址。

    注意:

    1.字符串相当于是一个数组,在内存中以数组的形式储存,只不过字符串是一个数组常量,

    内容不可改变,且只能是右值.如果看成指针的话,它即是常量指针,也是指针常量.

    2.str+1 也是一个指针,它指向数组的第1 号单元,它的类型是char**,它指向的类型是char*

      *(str+1)也是一个指针,它的类型是char*,它所指向的类型是char,它指向"Hi,goodmorning."的第一个字符'H'*/

 

    int array[10]= {0,1,2,3,4,5,6,7,8,9};

    int (*ptr)[10];

    int  *ptr1=&array;

    ptr=&array;

    int i;

    for(i=0; i<10; i++)

        printf("%d ",array[i]);

    printf("\n");

 

 

    for(i=0; i<10; i++)

        printf("%d ",*(ptr+i));//显示的地址.

    printf("\n");

 

 

    for(i=0; i<10; i++)

        printf("%d ",*(ptr1+i));

    printf("\n\n");

}

 

void pointer_array_and_array_pointer()

{

    ///指针数组的传参;相当于普通的一维数组。

    void print_fun011(char **str, int n)

    {

        int i;

        for ( i = 0; i < n; i++)

            printf("%s, ", *(str + i));

        printf("\n");

    }

 

 

    void sort_fun011(char **str, int n)

    {

        //冒泡排序..指针数组的排序非常有趣,因为这个数组中存放的是指针,

        //通过比较指针指向的空间的大小,排序这些空间的地址

        int j,i;

        char *tmp;

        for ( i = 0; i < n - 1; i++)

        {

            for ( j = 0; j < n - 1 - i; j++)

            {

                if (strcmp(*(str + j), *(str + j + 1)))

                {

                    tmp = *(str + j + 1);

                    *(str + j + 1) = *(str + j);

                    *(str + j) = tmp;

                }

            }

        }

    }

 

 

///数组指针:一个特殊的指针(步长特殊),指向一个数组。

    void print_fun012(char(*p)[10])

    {

        int i;

        for ( i = 0; i < 3; i++)

            printf("%s, ", *(p + i));

        printf("\n");

    }

 

 

    void sort_fun012(char(*p)[10], int n)

    {

        int j,i;

        char tmp[10];

        //选择排序

        for (i = 0; i < n ; i++)

        {

            for (j = i + 1; j < n; j++)

            {

                if (strcmp(*(p + i), *(p + j))> 0)

                {

                    strcpy(tmp, *(p + i));

                    strcpy(*(p + i), *(p + j));

                    strcpy(*(p + j), tmp);

                }

            }

        }

    }

 

 

    ///普通一维数组;数据类型是char [10]:(表示数组有10个元素,每个元素都是char型)

    char a[10];

    char *e ;    //e是一个一级指针,用来接收普通的一维数组

    e = a;            //e每次"+1",跳过一个(char 类型),即一个字节

    printf("e: %d,  e+1: %d \n", e, e + 1);

 

 

 

 

    ///指针数组相当于普通的一维数组,不过数据类型是 char *[5]:(表示数组有5个元素,每个元素都是char 型的指针);

    char *str[5] = { "sdada", "saadq", "wqeqwe", "12sda", "wq32r" };

    char **w ;    //w是一个二级指针,接收指针数组。 char **w = NULL;

    w = str;            //w 每次 "+1" 跳过1(char *类型),即四个字节(32bit平台)。

    printf("w: %d,  w+1: %d \n", w, w + 1);

 

 

    printf("排序前");

    print_fun011(str, 5);

    printf("排序后");

    sort_fun011(str, 5);            //数组内容重新排序(两个有本质区别,这个只是地址交换)

    print_fun011(str, 5);

 

    ///数组指针:一个指向数组的指针,(这个指针带有特殊的步长)。

    char str1[3][10] = { "asdqw", "123124", "xvzxc" };

    char buf2[][10] = { "111111", "3333333", "222222" };

    char(*q)[10]; //q是一个指针,每次 "+1" 10个字节(即10char 元素)的指针。

    q= str1;

    // printf("q: %d,  q+1: %d \n", q, q + 1);

 

 

    //printf("排序前");

    // print_fun012(buf2);

 

 

    //printf("排序后");

    sort_fun012(buf2, 3);    //数组内容重新排序(这个是二维数组,行地址不能直接交换,因为它的拥有内存,

    // 是一个一维数组,单纯的地址交换,将使一维数组的首地址丢失。

    //print_fun012(buf2);

    printf("\n");

    system("pause");

 

 

    /*:

    1.什么是指针数组和数组指针?

 

    指针数组:即”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,

    即这个数组的所有元素都是指针类型,在32位系统中,指针占4个字节。

 

    数组指针:即”数组的指针”,首先这个变量是一个指针,其次,”数组”修饰这个指针,

    即这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。

    二者根本就是种 类型的变量。

 

    2.指针数组传参时的使用:

    传递数组的首地址,用一个指针接收这个地址。因此,指针数组对应着二级指针

    void fun(char **pp);//子函数中的形参

    fun(char *p[]);//主函数中的实参

 

    3.数组指针传参时的使用:

    数组指针既然是一个指针,那么就是用来接收地址,在传参时就接收数组的地址,所以数组指针对应的是二维数组。

    void fun(int (*P)[4]);//子函数中的形参,指针数组

    a[3][4] = {0};//主函数中定义的二维数组

    fun(a);//主函数调用子函数的实参,是二维数组的首元素首地址

 

    */

}

 

void pointer_address()

{

     int a[4] = {1,2,3,4};

     int * p = a;

     printf("*p = %d\n",*p);

     printf("*(p+1)= %d\n",*(p+1));

     printf("*(p+2)= %d\n",*(p+2));

     printf("*(p+3)= %d\n",*(p+3));

 

 

     ///整型变量

    int aa = 10;

    int * pp;

    pp = &aa; //pp a 的第一个字节的地址.aa= 6356748  pp= 6356744;

    printf("aa= %d  pp= %d\n",aa,*pp);

 

 

    pp = aa;  //pp a 的第一个字节的地址.aa= 6356748  pp= 6356744;

    printf("aa= %d  pp= %d\n",aa,pp);//aa= 10  pp= 10  

    

    

    ///整型数组变量

    int bb[10]={1,2,3,4,5};//bp= 6356708  bp+1= 6356716;

    int *bp;

    bp = &bb;

    printf("bb= %d  bp= %d\n",&bb,&(*(bp)));//bb= 6356708  bp= 6356708

    printf("bb= %d  bp= %d\n",&bb,&bp);     //bb= 6356712  bp= 6356708

    

    /*

    bp[0]= 6356708  bp+0= 6356708

    bp[1]= 6356712  bp+1= 6356712

    bp[2]= 6356716  bp+2= 6356716

    bp[3]= 6356720  bp+3= 6356720

    bp[4]= 6356724  bp+4= 6356724

 

 

    bb[0]= 6356708  bp+0= 6356708

    bb[1]= 6356712  bp+1= 6356712

    bb[2]= 6356716  bp+2= 6356716

    bb[3]= 6356720  bp+3= 6356720

    bb[4]= 6356724  bp+4= 6356724*/

    printf("int= %d\n",sizeof(int));    

    

}

int main()

{

    //pointer_access();

    //pointer_array_foreach();

    //pointer_access_overflow();

    //pointer_add();

    //pointer_expression();

    //pointer_operator();

    //pointer_array();

    //pointer_array_and_array_pointer();

    //pointer_address();

  

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值