C语言指针2

一:指针的运算

    两个指针之间的减法运算

    前提:

    两个指针必须指向同一个数组

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

    int *p = &a[1];

    int *p1 = &a[4];

    printf("%d\n",p1-p); // &a[1]-&a[4]是地址差值,而p1-p是元素个数差值

 

    注意:

    指针之间是没有加法运算的

    两个指针相加的话,可能会越界

 

二:指针和二维数组

 

   int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

    //定义一个行指针,[4]表示这一行有四个元素

    int (*p)[4];//二维数组的行指针

    //表示把二维数组名赋值给指针变量p

    p = a;

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

    for (int j=0; j<4; j++)

        //a[i]  每一个行的地址

        //a[i]+j a[i][j]的地址

        //*(a[i]+j)  a[i][j]的元素的值

        //在一维数组中 a[i]值,*(a+i)

        //printf("%d ",*(a[i]+j));

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

        printf("%d ",*(*(p+i)+j));

    注意:数组名为数组首地址,并且是常量,不能赋值

 

三:字符串存储方式:

    1)使用字符数组

    char c1[]="adsfasdfas";

    //c1是数组的首地址,常量

    c1 = "asdfasdfasdf";(错误的)

 

    2)字符串指针

    格式:char *指针变量名

 

    1)字符串指针跟字符指针的区别

    赋值区别

    char c=‘a‘;

    char *s=&c;    //字符指针

    char *s1="dafasdfdsa";  //字符串指针

    2)字符数组和字符串指针的区别

    1)字符数组存放在 内存的栈 区

    2) 字符串指针指向的字符串存储在 内存常量区

    char *str="asdfsdfas";  //str指针变量,把字符串的首地址存放到str中

    char *str2;  //指针变量

    str2 = "adsfasdfasdf";

 

    注意:

    //定义char类型的数组

    //存放到内存的栈区,可以读也可以写

    char c[10]="itcast!";

    c[5]=‘A‘;

 

    //str存放的是常量字符串的首地址

    //str可以重新指向一个新的字符串,但是字符串的内容不能改

    char *str="itcast!";

    printf("%s\n",str);

    //str[5]=‘A‘;

 

四: 字符数组

    char ch[]="I need AV";

    char ch1[]="I need AV";

 

    字符串数组

    1)二维的字符数组存储

    char arr[3][20]={"dafasdf","I need AV","I need AV"};

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

        printf("%s\n",arr[i]);

    }

    存在栈区:arr[0]  arr[1]   arr[2]    //可读可写

 

    2)char型的一维指针数组

    //数组中每一个元素都是指针

    char *name[5]={"china","usa","hanguo","chaoxian","I need AV"}

    for(int i=0;i<5;i++){

        printf("%s",name[i]);

    }

    name[0]  name[1]    //常量区,不能改

 

五:1)为什么说scanf和gets是不安全的

 

    char ch[10];

    //从键盘接收一个字符串

    scanf("%s",ch);    //如果输入的字符串有空格,scanf就认为输入结束了,空格之后的字符都不会被报存

    gets(ch);          //可以接收用户输入的字符中含有空格

    //scanf和gets都有一个缺点:

    用户输入多少东西,就帮你保存多少东西

    aaaaaaaaaABBBBB

    假设用户输入的长度>10       15   = 10存数组     5连续存了(不安全的)

    puts()   //输出到缓冲区

 

    2)fgets()   fputs()   //安全的函数

    char ch1[10];

    9个字符+‘\0‘  安全的

    fgets函数主要功能是从文件中读取数据到字符数组

    格式:fgets(数组名,长度,stdin);    stdin 表示标准的输入,从输入缓冲区获取数据

 

    注意:

    1)fgets() 读取‘\n‘ 换行符      fgets获取的字符长度小与数组长度的时候,能看到

    2)                           如果输入的长度大于数组长度,会自动截断

    3) if (ch[strlen(ch)-1]==‘\n‘) ch[strlen(ch)-1]=‘\0‘;

 

    fputs()//可以写入字符串到文件中

    格式:fputs(数组名,stdout);    //stdout表示输出到控制台

    注意:fputs不能换行,puts可以自动换行,printf也不能自动换行

 

六: // 1、修饰变量,可以让变量变成只读的(常量)

    const int a = 10; 一般情况不能修改

    int *p;

    p = (int *)&a;

    *p = 5; printf("%d\n",*p);// 但是不要这么用

 

    // 2、const修饰指针

    1)const的作用是指针的指向可以改变,指针指向的变量的值不能改

    //    const int *p=&b;

    //    int const *p=&b;

    //    p = &c; 能改

    //    *p = 10; 不行

 

    //2)const的作用是,指针的指向不能改变,指针的指向的变量的值可以改变

    //    int * const p1 = &b;

    //    p1 = &c; 不可以

    //    *p1 = 30; 可以

 

    //3)此处的const表示,指针的指向和指向变量的值都不能改变

    //    const int * const p2 = &b;  //可以这样写

    //    p2 = &c; 不可以

    //    *p2 = 40; 不可以

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。