指针 与 数组

1  指针

  指针变量也是一个变量       指针存放的内容是一个地址,该地址指向一块内存空间。

  指针是一种数据类型

2  指针变量的定义  指针类型(int * ) + 变量名 ( p ):   比如: int * p;这里就定义了一个int * 类型的变量:p;p是变量名,p所代表的内存空间里面存放着的是一个地址;回头看p的类型是什么:是“int * ”注意了,不是int,而是在int后面加了一个“*”;那么,p是一个int * 类型的指针变量。这里还有一个概念,就是间接访问:已经知道了p这个指针变量里面存放的是一个地址;那这个地址指向的另外一块空间,它里面的值是什么呢,它就是一个int类型的值。以“*”符号为中心点,向左边结合,表示指针类型:int *;向右边变量结合,表示间接访问:*p  ; 看这一行代码:char *p = "i love you!"; “i love you!”编译器会把他们放在字符串常量区,那么,p的值就是这串英文的常量区地址。间接访问看下面的示例:

#include <stdio.h>

int main()
{
   char *p = "I Love You!";
    while(*p!=0)
    {
        printf("%c \t",p[0]);
        p++; //地址+sizeof(char)
    }
   printf("\n");
   
   return 0;
}

运行:

I   L o v e   Y o u !

高亮部分 *p!=0  ,这里就是间接访问,字符串数组中,数组成员多少个,就有多少个*P;遍历能打印出所有成员。

 


 

数组 和 指针

 看示例:

#include <stdio.h>

int main()
{
        int a[100]={1,2,3,4,5,6,7,8,9,10};
        int *p; 
        p = a;
        p[3]  = 100;

        int i;
        for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
        {   
                printf("a[%d] = %d\n",i,p[i]);
        }  

        return 0;
}

运行:

abc@ubuntu:~$ gcc -o pointer pointer.c
abc@ubuntu:~$ pointer
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 100
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a[9] = 10
abc@ubuntu:~$

当一个指针变量指向一个数组时,C语言规定指针变量名可以当数组使用。

再来看它们之间的区别1:指针大小在同一系统下是不变的,32位系统是4BYTE,64位系统是8BYTE。

#include <stdio.h>

int main()
{
        int a[10] = {1,2,3,4,5,6,7,8,9,10};
        int *p; 
        p = a;
        p[3] = 100;
        printf("%lu,%lu\n",sizeof(a),sizeof(p));
        int i;
        for(i = 0; i <sizeof(a)/sizeof(a[0]); i++)
        {   
                printf("a[%d] = %d\n", i, p[i]);
        }   
        return 0;
}

数组的大小是40,指针的大小始终不变。

运行:

abc@ubuntu:~$ gcc -o pointer pointer.c
abc@ubuntu:~$ pointer
40,8
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 100
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a[9] = 10
abc@ubuntu:~$

#include <stdio.h>

int main()
{
        int a[10] = {1,2,3,4,5,6,7,8,9,10};
        int *p; 
        p = a;
        p[3] = 100;
        a[4] = 500;
        printf("%lu,%lu\n",sizeof(a),sizeof(p));
        int i;
        for(i = 0; i <sizeof(a)/sizeof(a[0]); i++)
        {   
                printf("a[%d] = %d\n", i, a[i]);
        }   
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o pointer pointer.c
abc@ubuntu:~$ pointer
40,8
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 100
a[4] = 500
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a[9] = 10
abc@ubuntu:~$

修改为数组命名,结果一样。

再看:数组和指针的区别2

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5         int a[10] = {1,2,3,4,5,6,7,8,9,10};
  6         int *p;
  7         p = &a[5];
  8         p[3] = 100;
  9         a[4] = 500;
 10         printf("%lu,%lu\n",sizeof(a),sizeof(p));
 11         int i;
 12         for(i = 0; i <sizeof(a)/sizeof(a[0]); i++)
 13         {
 14                 printf("a[%d] = %d\n", i, a[i]);
 15         }
 16         return 0;
 17 }

运行:

abc@ubuntu:~$ gcc -o pointer pointer.c
abc@ubuntu:~$ pointer
40,8
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 500
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 100
a[9] = 10
abc@ubuntu:~$

代码中把a[5]的地址给了指针变量,那么指针p就把a[5]的地址认为p[0],p[1],p[2],p[……]地址依次向后。所以修改p[3]的值,就会是a[8]的值。

 指针的计算

#include <stdio.h>

int main()
{
        int a[10]= {0};
        int *p = a; 
        p += 5;
        *p = 1;
        p -= 2;
        *p = 3;
        int i ; 
        for(i = 0; i<sizeof(a)/sizeof(a[0]); i++)
        {   
                printf("%a[%d] = %d\n",i, a[i]);
        }   
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o p_count p_count.c
abc@ubuntu:~$ p_count
a[0] = 0
a[1] = 0
a[2] = 0
a[3] = 3
a[4] = 0
a[5] = 1
a[6] = 0
a[7] = 0
a[8] = 0
a[9] = 0
abc@ubuntu:~$

 看代码,首先int *p = a ;  这时p还和a下标对应,到了p+= 5;这时p[0]指向就向后面移动了5个空间,对应a[5]了。p -=2;就再把p[0]指向向前移动了2个空间,指向了a[3],最后*p=3;就是修改的p[0]对应的a[3]。

指针可以加,可以减,但不可以乘除。

 

#include <stdio.h>

int main()
{
        int a[] = {1,2,3,4,5,6,7,8,9,10};
        int *p = a;  //指针p指向a的首地址
        //p[3] = 100;
        *(p+3) = 100;
        int i;
        for(i = 0; i< sizeof(a)/sizeof(a[0]); i++)
        {   
                printf("a[%d] = %d\n",i, a[i]);
        }   


        return 0;
}

运行:

abc@ubuntu:~$ gcc -o count_p count_p.c
abc@ubuntu:~$ count_p
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 100
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a[9] = 10
abc@ubuntu:~$

 再看:

#include <stdio.h>

int main()
{
    unsigned int num = 987654321;
    unsigned char *p =(unsigned char *)&num;
    //p =(char *)&num;
    int i;
    for (i = 0; i<4; i++)
    {
        printf("num[%d] = %d\n",i, p[i]);
    }

    return 0;
}

 

 示范:输入一个Ip地址,转换成整数

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


bool IsBigEndian()
{
    short int n = 0x1122;//十六进制,一个数值占4位
    char c = *(char *)&n;  //通过将short(2字节)强制类型转换成char单字节,c指向n的起始字节(低字节)
    if (c == 0x11)//低字节存的是数据的高字节数据
    {
        //是大端模式
        return true;
    }
    else
    {
        //是小端模式
        return false;
    }
}

int main()
 {    
    char a[255] = {0};
    scanf("%s.%s.%s.%s", &a);
    unsigned int ip = 0;
    unsigned char * p = (unsigned char *)&ip;
    unsigned int a1, a2, a3, a4;
    sscanf(a,"%u.%u.%u.%u", &a1, &a2, &a3, &a4);
    //判断大小端
     if (IsBigEndian())
     {
         *p = a1;
         p++;
         *p = a2;
         p++;
         *p = a3;
         p++;
         *p = a4;        
     }
     else
     {
         *p = a4;
         p++;
         *p = a3;
         p++;
         *p = a2;
         p++;
         *p = a1;
     }
    
    printf("%u", ip);
    return 0;
}

运行:

 

 

#include <stdio.h>

int main()
{
    char a[2][5] = {{16,3,6,2,9},{56,32,8,1,98}};
    char *p = (char *)a;

    int i, j;
    for (i = 0; i < sizeof(a); i++)
    {
        for (j = 1; j < sizeof(a)-i; j++)
        {
            if (p[j] < p[j - 1])
            {
                char tmp = p[j-1];
                p[j-1] = p[j];
                p[j] = tmp;
            }
        }
    }
    for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
        for (j = 0; j < sizeof(a[0]) / sizeof(a[0][0]); j++)
        {
            printf("%d\n", a[i][j]);
        }
    }
    return 0;
}

把二维数组看成一维数组的char指针冒泡。运行:

 

 


指针数组

二级指针

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2016-12-25 13:06  zzdoit  阅读(178)  评论(0编辑  收藏  举报

导航