C语言基础之指针续


一、指针

(1)、指针与数组

#include <stdio.h>
int main()
{
    int ages[]={23,12,32,11};
    int *p;
    
    //下面两句其实是等价的,数组名本身就代表数组地址
    p=ages;
    p=&ages[0];
    
    
    printf("p---%p\n",p);//指针指向数组首元素,因此打印的是数组地址
    printf("*p---%d\n",*p);//指针指向数组首地址,其指向地址中的值就是ages[0]
    
    /*
     p+1代表的是下一个元素地址,取决于指针类型,
     若指针是int类型,加1代表加了4个字节。
     若指针是char类型,加1代表加了1个字节。
     */
    printf("p---%p\n",p+1);//ages[1]的地址
    printf("*p---%d\n",*(p+1));//ages[1]的值
    
    //遍历数组
    for(int i=0;i<sizeof ages/sizeof(int);i++)
    {
        printf("ages[%d]----%d\n",i,*(p+i));
    }
    
    //p[i]这种访问方式也是可以的
    printf("%d\n",p[2]);//就是ages[2]的值
    
    return 0;
}

总结:

1.数组元素的访问方式

  1>数组名[下标] 如ages[2]

  2>指针变量名[下标] 如p[2]

  3>*(p+i)

2.指针变量的+1,究竟加多少,取决于指针的类型

#include <stdio.h>

void test(int *array)
{
    printf("array+2----%d\n",*(array+2));
    printf("array+2----%p\n",array+2);
}
int main()
{
    int a=89;
    int ages[]={23,12,32,11};

    /*
     ages[1]的地址传给指针array,那么array+2,就是从ages[1]开始往后推8个字节
     就是ages[3]的值
     */
    test(&ages[1]);
    
    /*
     ages[2]的地址传给指针array,那么array+2,就是从ages[2]开始往后推8个字节
     变量a在数组后面,所以array+2此时指向的是变量a
     */
    test(&ages[2]);
    printf("ages[3]的地址是---%p\n",&ages[3]);
    printf("a的地址是---%p\n",&a);
    
    
    return 0;
}
2、指针和字符串

C语言数组是放在栈内存中的。所以用字符数组定义的字符串是存放在栈内存中的变量。而字符指针定义的数组是存放在常量区中的,是一个常量,方便下次使用。

#include <stdio.h>

int main()
{
    char c[]="sdfg";
    c[2]='e';
    printf("%s\n",c);
    
    char *name="nike";//指针指向字符串的首地址
    //*name='e'; 运行时会崩溃,因为这个字符串是个常量
    printf("%s\n",name);
    
    //用指针定义的字符串是不能改变的,在常量区缓存起来,下次再定义该字
    //符串时不会另开辟空间,而是用之前定义的那个.
    char *name1="nike";
    //下面两个地址是相同的
    printf("name------%p\n",name);
    printf("name1-----%p\n",name1);
    
    return 0;
}
总结:

1.定义字符串的两种方式

1>利用数组

 char name[]="it";

 特点:字符串里面的字符是可以修改的

 使用场合:字符串的内容需要经常修改

2>利用指针

 char *name="it";

 特点:字符串是一个特常量字符串,里面的内容不能修改

 使用场合:字符串的内容不需要修改,且这个字符串经常使用

#include <stdio.h>

int main()
{
    //字符串数组两种定义方式
    char *name[]={"it","de"};
    char name1[2][10]={"int","double"};
    
    printf("%s\n",name[1]);
    printf("%s\n",name1[1]);
    
    
    //输入字符串,这就用字符串数组了
    char name2[10];
    printf("请输入一个姓名\n");
    scanf("%s",name2);//%s就是从name2这个地址开始一个一个输入
    printf("姓名是--%s\n",name2);
    return 0;
}
3、返回指针的函数
#include <stdio.h>
#include <string.h>

char *test();
int test1(char *);
int main()
{
    char *a=test();
    printf("%s\n",a);
    
    //指向函数的指针
    /*
     (*p)是固定格式,代表指针变量p将来肯定指向函数
     int代表指针变量p指向的函数返回值类型是int
     (char *)代表指向的函数参数
     函数名本身就是函数地址
     */
    //定义了一个函数指针并初始化
    int (*p)(char *)=test1;
    //以下三种调用方式都是正确的
    int i=p("jihui");
    int j=(*p)("nihao");
    int l=test1("哈哈");
    
    printf("i----%d\nj-----%d\nl----%d\n",i,j,l);
    
    return 0;
}


//返回指针的函数
char *test()
{
    return "nihao";

}
//返回字符串字节数
int test1(char *c)
{
    return strlen(c);
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值