• 再谈一维数组、二维数组与指针、数组指针


    首先看如下一下基础:

       一、int *p:p是指向一个整数变量的指针(int *p=&i    ,p指向整型变量i )

       char *p:p是指向一个字符变量的指针

     由int data[30]; int *p;有p=data;或p=&datd[1](i=0,1,2,3....)

     上面成立的原因:(1)数组名是该数组首元素的地址

                            (2)&data表示取整个数组的地址,包括多维数组。&data[0]取数组首个元素的地址。单独data则亦表示数  组首元素的地址。

                             (3)p是p是指向一个整数变量的指针

         二、 int a[3][4];a是指向由4个int数据构成的数组的指针

                int (*p)[4];p是指向由4个int数据构成的数组的指针

          于是必然有:p=a;

          分析二成立的原因:1、c primer plus中对二维数组和数组指针的定义即是上面的方式;

                                    2、因为在数组与指针中有p[m]=*(p+m)的关系。直接将上面的数组指针int (*p)[4];改写

    成int (*p+0)[4];即等效于int p[0][4];自然可以很清晰的理解了。

          三、字符的存储形式:每个字符以整数的形式储存。

                字符串的储存方式:一“”结尾的char数组。

         四、c语言中字符串,就是字符数组,故指针访问字符串即等效于指针访问数组元素。

          1)、数组与数组,数组与指针,指针与指针之间的赋值

           数组之间是不可以直接赋值的,要直接赋值的话,也只能是利用循环,一个一个的赋值:

     #include<stdio.h>
    int main()
    {
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    int b[10]={1,2,3,4,5,6,7,8,9,10};
    for(int i = 0;i<10;i++)

    {
    a[i]=b[i];       (可以为*(a+i) = *(b+i) )
    }
    return 0;
    }

    当然还可以通过其他方法来实现,比如取地址运算,把数组a的首地址赋给B数组,不过这要通过指针来实现:

    #include<stdio.h>
    int main()
    {
    int k;
    char *s[]={"you","are","the","one"};
    char **q;
    for(k=0;k<4;k++)
    {
      *q[k]=*s[k];
      printf("%s ",*q[k]);
    }
    }

    还有一种简单点的方法就是拷贝运算,你可以利用c语言库里面已经定义好的函数直接实现你所要实现的功能,实现方法如下:

    #include <string.h>
    #include <stdio.h>
    void main()
    {
    char a[10]={"asdsadsa"},b[10];
    strcpy(b,a);
    printf("%s ",b);
    }

       五、两个指针之间的赋值则就是根据数组间的赋值就可以了,只需利用( a[i] = *(a+i) ,i=0,1,2,3,4.....)

       六、指针字符与字符数组之间的关系 

            采用指针存储字符串,其实质就是把字符串的首地值附给基类型为char的指针变量,从而可以从字符串首元素开始对字符串进行操作,但是,,这里面也存在一点问题,如下:    
            int main()
             {
                char *p="hello";
                p[0]='M';
                printf("%s ",p);
                return 0;
              }
         运行结果会出现断错误,原因在于,*p="hello" 这句仅仅声明了一个指针变量,指向字符串"hello ",而"hello "这个字符串程序没有给它分配空间,编译器把它分配到常量区.而常量字符串的值是不允许被修改的 ,所以会出现断错误.
     
     
           程序改为如下就正确了
            int main()
            {
               char p[12]="hello";
               char *p1=p;
               p1[0]='M';
               printf("%s ",p1);
               return 0;
            }   
         
          因为,p[12]="hello "是你自己定义的一个长度为12 的字符数组,所以字符串"hello world"编译器会给它分配空间(在栈中及非常量区),所以可以修改它的值. 
    字符串“hello”本身就是一个常量字符指针,而对于指针p,无非就是一个地址的拷贝,也就是“hello”地址的拷贝,相当于p指向一个字符串常量,字符串常量是不予许改变的!
    而对于p[]来说就不一样了,虽然hello本身是常量,不过此时拷贝给p[]的不是地址,而是内容,也就是“hello”,也就是p本身拥有一个自己的hello副本,可以对其进行想要的合法操作,比如改变等.
     
    最后说明:
    c语言中,不能对字符指针变量指向的字符串再赋值,这不是绝对正确的:当指针指向的字符串是常字符串时当然不能再赋值,因为目标是“常量”,而当指针指向的字符串不是常字符串时就可以再赋值,比如用动态申请内存方法创建的字符串。具体说就是用char *p="abcqer12345";这种方法定义字符串是不能通过指针改变内容的,原因是这个定义确定了abcqer12345是字符串常量——因为char *p="abcqer12345";被编译器解释为“创建一个字符串常量abcqer12345,并把它的首地址(就是a的地址)赋给char *型指针p。
     而如果用动态申请内存时基本方式如下:
    在C语言中,动态申请内存可以用stdlib.h中声明的malloc函数。

    函数原型:

    void *malloc(unsigned int num_bytes);

    num_bytes为要申请的内存数量。申请成功,则返回指向这块内存的指针;失败则返回NULL。

    申请成功之后,就可以使用gets来接收字符串。代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        int size = 100;
        char *str;
        
        str = malloc(size);
        gets(str);
        puts(str);
        free(str);
        
        return 0;
    }
     
       七、 补充知识:指针

       指针在定义后必须要先初始化才能使用,因为未初始化的指针指向哪里,根本就不知道,使用后结果不可预知,如果指向的内存中比较重要的地方,可能会导致系统异常,如提示指向了一个不可用的地址之类。

       对指针进行初始化,有三种方法:

    1. 运用int *p=0;这个语句老老实实的将指针初始化了;
    2. 把int *p=0和p=&i这两句话连成一句话: int *p=&i(&i可以用a,当a表示已定义的数组或已有所指的指针等);这样,就既把指针变量p初始化了,又把它指向了某个值;
    3. 用常量来初始化一个指针。则需用强制类型转换,找一个内存地址,即(ElementType *) 来把常量转换成内存中的一个地址。既采用:
    ElementType *p=(ElementType *)[常量]
  • 相关阅读:
    ActionMQ
    解决Session共享
    Linux中使用keepalived高可用工具解决宕机问题
    Linux安装Nginx
    Nginx基础
    多线程(1)
    单例模式1(3)
    创建型模式5种(2)
    7原则(1)
    反射使用案例(2)
  • 原文地址:https://www.cnblogs.com/wgang171412/p/5125348.html
Copyright © 2020-2023  润新知