指针简单应用

写了没用上(本来给新生写的),算了,丢博客吧,就当纪念一下,顺便可以复习(虽然说可能用不上罢了)

如果有什么错滴滴我(虽然说可能也没多少人看罢了)

// 指针的简单应用
/*
参考链接https://www.runoob.com/cprogramming/c-pointers.html
上述链接里面讲的已经很详细了,建议去看QAQ
*/
/*
废话:
因为部分人可能之后也不会用c艹什么的,所以这都是c语言写的(毕竟考试考的是c么)
指针刚开始学起来发现挺痛苦的,但是,到后面你就会发现大一下学期数据结构还是要学滴
这代码我一个人写的,可能会有些地方有错误或者写的不详细,见谅QAQ
*/
#include <stdio.h>
#include <stdlib.h>
void test1() // 指针基本用法
{
    int a = 10;
    printf("a的地址为%p\n", &a);  // 输出a的地址    %p 以16进制的形式输出内存地址
    printf("a的值为%d\n\n", *&a); // 输出a的值(可知*&a等于a,即*和&可以抵消)   %d 输出有符号十进制整数
    /*
    我们可以看到平常我们用的printf中'&'实际上是取地址的意思~~
    而'*'用来来返回位于操作数所指定地址的变量的值
    */

    int *ip; // 定义一个int类型指针,不过指针最好要进行赋值,没经过赋值的指针叫做“野指针”(即不知道指向哪里)
    ip = &a; // 将a的地址赋值给指针
    // 上述也可以转换为:    int *ip=&a;
    /*
    同时指针没有确切的赋值可以用NULL 如ip=NULL
    赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。
    NULL的地址为0x0
    */
    printf("ip的值为%p\n", ip);
    printf("ip指向的地址的值为%d\n\n", *ip);
    /*
    我们可以发现ip的值为a的地址,ip指向的地址的值为a的值(废话QAQ)
    */
}
void test2() // 指针大小
{
    int *_int_;
    char *_char_;
    double *_double_;
    float *_float_;
    short *_short_;
    printf("int指针的大小为:%d\n", sizeof(_int_)); // sizeof函数用处:返回一个变量或者类型的大小(以字节为单位)
    printf("char指针的大小为:%d\n", sizeof(_char_));
    printf("double指针的大小为:%d\n", sizeof(_double_));
    printf("float指针的大小为:%d\n", sizeof(_float_));
    printf("short指针的大小为:%d\n\n", sizeof(_short_));
    /*
    我们可以发现上述指针大小都是一样的(32位系统和64位系统跑的可能不一样)
    why?
    毕竟指针是来存地址的(也就是%p输出的那大串),不同类型的指针只是指向的类型不一样罢了
    */
}
void test3() // 指针的算术运算
{
    int x;
    int *_ip_ = &x;
    printf("_ip_的地址为:%p\n", _ip_);
    printf("_ip_ +1的地址为:%p\n\n", _ip_ + 1);
    /*
    我们可以看到指针地址的算术运算并不是地址加1,而是地址加上一个4
    */
    // 指针的算术运算和其他的差不多所以不码了(欸,就是偷懒~~)
}
void test4() // 杂,基本用不到
{
    /*
    int num = 0x10203040;
    int *p1 = &num;
    short *p2=&num;//这里可能会报warning,但只是警告而已,并不代表错误
    printf("int类型 *p1=%p\n",*p1);//10203040
    printf("short类型 *p2=%p\n",*p2);//3040
    printf("short类型 *(p2+1)=%p\n",*(p2+1));//1020
    */
    /*
    num在linux/window系统里是倒着存数据的
    即你赋值0x10203040,但是存的数据可能是0x40302010
    */
}
void test5() // 指针套指针
{
    int num = 10;
    int *p1 = &num;
    int **p2 = &p1;
    printf("p1=%p\n", p1);
    printf("*p1=%d\n", *p1);
    printf("*p2=%p\n", p2);
    printf("**p2=%d\n", **p2);
    // 没啥说的,只是'*'和'&'的反复纵跳而已
}
void test6() // 指针与数组的简单应用
{
    int num[] = {1, 2, 3};
    int *p = num;
    p[1] = 22; // 可以直接用下标来对数组进行赋值
    printf("num[1]=%d", num[1]);
}
void test7() // 指针常量与常量指针
{
    int a = 10, b = 5;
    int *const p1 = &a; // 指针常量
    *p1 = 0;            // 成功
    // p1=&b;//失败
    /*
        即指针常量不能改地址
    */
    const int *p2 = &a; // 常量指针
    //*p2=0;//失败
    p2 = &b; // 成功
    /*
     即常量指针不能改数的值
    */
}
void test8() // 指针数组与数组指针
{
    int a = 1, b = 2, c = 3;
    int num[3] = {a, b, c};
    int *p1[3];  // 指针数组   即3个int型的指针
    int(*p2)[3]; // 数组指针 即1个数组类型的指针
    // 用法
    p1[1] = &a;
    p2 = &num;
}
void test9_1(int x, int y) // 错误示范
{
    int temp = x;
    x = y;
    y = temp;
}
void test9_2(int *x, int *y) // 正确示范
{
    int temp = *x;
    *x = *y;
    *y = temp;
}
void test9() // 指针交换两个数的值
{
    int a = 10, b = 5;
    printf("a=%d,b=%d\n", a, b);
    test9_1(a, b); // 值传递,不能改变这里ab的值,即这函数拷贝对应的值过去了
    printf("a=%d,b=%d\n", a, b);
    test9_2(&a, &b); // 地址传递,能改变这里ab的值,根据传递过去的地址用*找到地址对应的值,并且进行了修改
    printf("a=%d,b=%d\n", a, b);
}
int *test10_1(int x) //错误示范
{
    int a=10;
    int *p = &a;
    return p;
    //这只是个示范,即告诉你指针函数是函数返回一个指针,但是实际上最好别这么做(返回函数里面的变量)!!!详细看以下
}
int *test10_2(int x)  //这种返回一个指针的才是指针函数
{
    int *p = (int *)malloc(sizeof(int));//malloc为stdlib.h中的一个函数,用来分配内存
    *p=x;
    return p;
}
void test10() // 指针函数(test10不是指针函数)
{
    int a = 10;
    int *ip = test10_1(a);//错误示范
    printf("test1---*ip=%d\n", *ip);//正常输出10
    printf("test1---*ip=%d\n", *ip);//错误输出
    /*
    原因:发生了 悬挂/悬空 指针错误,因为函数返回的地址是一个临时的变量的地址(这里是x),
    当函数结束的时候,这个空间也就会释放,值也就可能不是原本的值了
    至于第一次正常输出好像是因为有保护机制(再问下去我这个蒟蒻也不知道啊~~~QAQ)
    解决办法:返回static修饰的变量/全局变量的地址,用malloc动态内存分配,等等……
    (反正就是一般别返回函数里面定义的变量啦,会被回收机制释放的(毕竟要保证所指向的地址对应的值不会被垃圾回收就行啦))
    */
    ip = test10_2(a);//正确示范
    printf("test2---*ip=%d\n", *ip);
    printf("test2---*ip=%d\n", *ip);
}
int test11_add(int x, int y)
{
    return x + y;
}
int test11_sub(int x, int y)
{
    return x - y;
}
void test11() // 函数指针
{
    int a = 10, b = 5;
    int (*fun)(int x, int y); // 函数指针(指向函数的指针)
    // 简单用法:
    fun = test11_add;
    printf("test11_add(a,b)=%d\n", fun(a, b));
    fun = test11_sub;
    printf("test11_sub(a,b)=%d\n", fun(a, b));
}
struct test12_age
{
    int year, month, day;
};
void test12() // 指向结构体变量的指针
{
    struct test12_age a = {1, 2, 3}; // 定义结构体变量并且赋值
    struct test12_age *p = &a;
    printf("year=%d,month=%d,day=%d\n", a.year, a.month, a.day);          // 结构体变量.成员名
    printf("year=%d,month=%d,day=%d\n", p->year, p->month, p->day);       // 用法1  指针变量->成员名
    printf("year=%d,month=%d,day=%d\n", (*p).year, (*p).month, (*p).day); // 用法2  (*指针变量).成员名
}
int main()
{
    //  test1();//指针基本用法
    //  test2();//指针大小
    //  test3();//指针算术运算
    //  test4();//杂,数据存放(逆序存放)
    //  test5();//指针套指针
    //  test6();//指针与数组的简单应用
    //  test7();//指针常量与常量指针
    //  test8();//指针数组与数组指针
    //  test9();//指针交换两个数的值
    //  test10();//指针函数
    //  test11();//函数指针
    //  test12();//指向结构体变量的指针
    // end   不码了,开摆!~
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值