C语言入门课程学习笔记9:指针

C语言入门课程学习笔记9

  • 第41课 - 指针:一种特殊的变量
    • 实验-指针的使用
    • 小结
  • 第42课 - 深入理解指针与地址
    • 实验-指针的类型
    • 实验
    • 实验
    • 小结
  • 第43课 - 指针与数组(上)
    • 实验
    • 小结
  • 第44课 - 指针与数组(下)
    • 实验
    • 实验
    • 小结
  • 第45课 - 指针与函数
    • 实验
    • 实验
    • 小结
  • 第46课 - 指针与堆空间
    • 实验
    • 实验
    • 小结
  • 第47课 - 指针专题经典问题剖析
    • 小结

第41课 - 指针:一种特殊的变量

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验-指针的使用

#include <stdio.h>

int main()
{
    int var = 0;
    int another = 0;
    int* pVar = NULL;

    printf("1. var = %d\n", var);
    printf("1. pVar = %p\n", pVar);

    pVar = &var;  // 使用指针保存变量的地址

    *pVar = 100;  // *pVar 等价于 var , var = 100;

    printf("2. var = %d\n", var);
    printf("2. pVar = %p\n", pVar);

    pVar = &another;  // 改变了 pVar 的指向,使得 pVar 保存 another 的地址

    *pVar = 1000;     // another = 1000;

    printf("3. another = %d\n", another);
    printf("3. pVar = %p\n", pVar);

    printf("4. add ==> %d\n", var + another + *pVar);   // 100 + 1000 + 1000  ==> 2100

    return 0;
}
/*
1. var = 0
1. pVar = 0000000000000000
2. var = 100
2. pVar = 000000000061FE14
3. another = 1000
3. pVar = 000000000061FE10
4. add ==> 2100
*/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

第42课 - 深入理解指针与地址

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验-指针的类型

#include <stdio.h>

int main()
{
    int i = 10;
    float f = 10;

    int* pi = &f;    // WARNING  int* 指向了float
    float* pf = &f;  // OK

    printf("pi = %p, pf = %p\n", pi, pf);
    printf("*pi = %d, *pf = %f\n", *pi, *pf);

    pi = i;   // WARNING  

    *pi = 110;  // OOPS

    printf("pi = %p, *pi = %d\n", pi, *pi);

    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int calculate(int n, long long* pa, long long* pm)
{
    int ret = 1;

    if( (1 <= n) && (n <= 20) )
    {
        int i = 0;

        *pa = 0;
        *pm = 1;

        for(i=1; i<=n; i++)//  0+1+...+n
        {			//1*1*...*n
            *pa = *pa + i;
            *pm = *pm * i;
        }
    }
    else
    {
        ret = 0;
    }

    return ret;
}

int main()
{
    long long ar = 0;
    long long mr = 0;

    if( calculate(5, &ar, &mr) )
        printf("ar = %lld, mr = %lld\n", ar, mr);//15   1*2*3*4*5=120

    return 0;
}

在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

void func(int* p)
{
    *p = 100;   // 修改内存中 4 字节的数据,即:修改一个整型变量的值
}

void swap(int* pa, int* pb)//通过指针交换变量
{
    int t = 0;

    t = *pa;
    *pa = *pb;
    *pb = t;
}

int main()
{
    int var = 0;
    int a = 1, b = 2;

    printf("1. var = %d\n", var);

    func( &var );

    printf("2. var = %d\n", var);//100

    printf("3. a = %d, b = %d\n", a, b);

    swap(&a, &b);

    printf("4. a = %d, b = %d\n", a, b);

    return 0;
}

小结

在这里插入图片描述

第43课 - 指针与数组(上)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int main()
{
    int a[] = {1, 2, 3, 4, 0};
    int* p = a;  // a 的类型为 int*, &a[0] ==> int*
    int (*pa) [5] = &a;//指向数组的指针  注意指针类型

    printf("%p, %p\n", p, a);

    p++;//p+1==== p+1*sizeof(p)

    *p = 100;  // a[1] = 100;

    printf("%d, %d\n", *p, a[1]);
    printf("%p, %p\n", &a, a);//????值一样 但是意思不一样,数组的地址  数组首元素的地址

    p = pa;   // WARNING  !!!!   warning: assignment to 'int *' from incompatible pointer type 'int (*)[5]' 

    p = a;

    while( *p )
    {
        printf("%d\n", *p);

        p++;
    }

    return 0;
}
/*
000000000061FDF0, 000000000061FDF0
100, 100
000000000061FDF0, 000000000061FDF0
1
100
3
4
*/

小结

在这里插入图片描述

第44课 - 指针与数组(下)

在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int main()
{
    int a[] = {1, 2, 3, 4, 5};
    int* p = a;
    int i = 0;

    // a[i] <==> *(a+i) <==> *(p+i) <==> p[i]

    for(i=0; i<5; i++)
    {
        printf("%d, %d\n", a[i], *(a + i));
    }

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

    for(i=0; i<5; i++)
    {
        printf("%d, %d\n", p[i], *(p + i));
    }

    printf("a = %p, p = %p\n", a, p);//值相同
    printf("&a = %p, &p = %p\n", &a, &p);//值不同

    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int main()
{
    int a[] = {1, 2, 3};
    int* p = a;
    int v = *p++;//int v=*p,p++;

    char* s = NULL;

    printf("%p\n", "D.T.Software");
    printf("%p\n", "D.T.Software");

    printf("v = %d, *p = %d\n", v, *p);

    printf("First = %c\n", *"D.T.Software");

    s = "D.T.Software";

    while( *s ) printf("%c", *s++);

    printf("\n");

    return 0;
}
/*
0000000000404000
0000000000404000
v = 1, *p = 2
First = D
D.T.Software
*/

小结

在这里插入图片描述

第45课 - 指针与函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int add(int a, int b)
{
    return a + b;
}

int mul(int a, int b)
{
    return a * b;
}

int calculate(int a[], int len, int(*cal)(int, int))
{
    int ret = a[0];
    int i = 0;

    for(i=1; i<len; i++)
    {
        ret = cal(ret, a[i]);
    }

    return ret;
}

int main()
{
    int a[] = {1, 2, 3, 4, 5};
    int (*pFunc) (int, int) = NULL;

    pFunc = add;

    printf("%d\n", pFunc(1, 2));//3
    printf("%d\n", (*pFunc)(3, 4));//7

    pFunc = &mul;

    printf("%d\n", pFunc(5, 6));//30
    printf("%d\n", (*pFunc)(7, 8));//56

    printf("1 + ... + 5 = %d\n", calculate(a, 5, add));//15
    printf("1 * ... * 5 = %d\n", calculate(a, 5, mul));//120

    return 0;
}

在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int demo(int arr[], int len)  // int demo(int* arr, int len)//数组求和
{
    int ret = 0;
    int i = 0;

    printf("demo: sizeof(arr) = %d\n", sizeof(arr));// 8 退化为指针了

    while( i < len )
    {
        ret += *arr++;

        i++;
    }

    return ret;
}

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

    // int v = *a++;

    printf("return value: %d\n", demo(a, 5));//

    return 0;
}

小结

在这里插入图片描述

第46课 - 指针与堆空间

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>

int main()
{
    char c = 0;
    int i = 0;
    float f = 2.0f;
    double d = 3.0;

    void* p = NULL;

    double* pd = NULL;
    int* pi = NULL;

    /* void* 指针可以保存任意类型的地址 */
    p = &c;
    p = &i;
    p = &f;
    p = &d;

    printf("%p\n", p);

    // void* 类型的指针无法访问内存中的数据
    // printf("%f\n", *p);

    /* void* 类型的变量可以直接合法的赋值给其他具体数据类型的指针变量 */
    pd = p;
    pi = p;

    // void* 是例外,其他指针类型的变量不能相互赋值
    // pd = pi;

    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int* p = malloc(4); // 从堆空间申请 4 个字节当作 int 类型的变量使用

    if( p != NULL )  // 如果申请失败 p 为 0 ,即:空值
    {
        *p = 100;

        printf("%d\n", *p);//100

        free(p);
    }

    p = malloc(4 * sizeof(int));

    if( p != NULL )
    {
        int i = 0;

        for(i=0; i<4; i++)
        {
            p[i] = i * 10;
        }

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

        free(p);
    }

    return 0;
}
/*
100
0
10
20
30
*/

小结

在这里插入图片描述

第47课 - 指针专题经典问题剖析

在这里插入图片描述

 #include <stdio.h>
#include <stdlib.h>

int main()
{
    int a = 0;
    int b = 1;

    int* p = &a;  //p指向a
    int** pp = &p;//pp指向p

    **pp = 2;   // a = 2;

    *pp = &b;   // p = &b;  

    *p = 3;     // b = 3;

    printf("a = %d, b = %d\n", a, b);

    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[] = {1, 2, 3, 4};
    int* pa = a;

    int b[2][2] = {{1, 2}, {3, 4}};
    // int** pb = b;  // b 的类型绝对不是 int**  warning: initialization of 'int **' from incompatible pointer type 'int (*)[2]'

    int (*pnb) [2] = b;  // b 的类型是 int(*)[2]

    printf("a = %p, pa = %p\n", a, pa);
    // printf("b = %p, pb = %p\n", b, pb);
    printf("b = %p, pnb = %p\n", b, pnb);

    return 0;
}
/*
a = 000000000061FE00, pa = 000000000061FE00
b = 000000000061FDF0, pnb = 000000000061FDF0
*/

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int getDouble(double** pp, unsigned n)
{
    int ret = 0;
    double* pd = malloc(sizeof(double) * n);

    if( pd != NULL )
    {
        printf("pd = %p\n", pd);
        *pp = pd;
        ret = 1;
    }

    return ret;
}

int main()
{
    double* p = NULL;

    if( getDouble(&p, 5) )
    {
        printf("p = %p\n", p);

        free(p);
    }

    return 0;
}
/*
pd = 00000000006E5CB0
p = 00000000006E5CB0
*/

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int b[2][2] = {{1, 2}, {3, 4}};
    int (*pnb) [2] = b;  // b 的类型是 int(*)[2]
    *pnb[0] = 10;//*(pnb[0])
    *pnb[1] = 30;

    printf("b[0][0] = %d\n", b[0][0]);
    printf("b[0][1] = %d\n", b[0][1]);//30
    printf("b[1][0] = %d\n", b[1][0]);
    printf("b[1][1] = %d\n", b[1][1]);

    return 0;
}
/*
b[0][0] = 10
b[0][1] = 2
b[1][0] = 30
b[1][1] = 4
*/

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int b[2][2] = {{1, 2}, {3, 4}};
    int (*pnb) [2] = b;  // b 的类型是 int(*)[2]
    *pnb[0] = 10;
int * k=pnb[0] +1;//??  pnb[0] +sizeof(*pnb[0])对了 
 *k= 20;
  //  *pnb[1] = 30;
printf("sizeof(pnb) = %d\n", sizeof(pnb));
printf("sizeof(pnb[0]) = %d\n", sizeof(pnb[0]));
printf("sizeof(*pnb) = %d\n", sizeof(*pnb));
printf("sizeof(*pnb[0]) = %d\n", sizeof(*pnb[0]));
printf("pnb=%p\n",pnb);
printf("pnb[0]=%p\n",pnb[0]);
printf("pnb[0]+1=%p\n",pnb[0]+1);

printf("sizeof(b) = %d\n", sizeof(b));
printf("sizeof(int[2]) = %d\n", sizeof(int[2]));

    printf("b[0][0] = %d\n", b[0][0]);
    printf("b[0][1] = %d\n", b[0][1]);//30
    printf("b[1][0] = %d\n", b[1][0]);
    printf("b[1][1] = %d\n", b[1][1]);

    return 0;
}
/*
sizeof(pnb) = 8
sizeof(pnb[0]) = 8
sizeof(*pnb) = 8
sizeof(*pnb[0]) = 4
pnb=000000000061FE00
pnb[0]=000000000061FE00
pnb[0]+1=000000000061FE04
sizeof(b) = 16
sizeof(int[2]) = 8
b[0][0] = 10
b[0][1] = 20
b[1][0] = 3
b[1][1] = 4
*/

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int* func()
{
    int var = 100;

    return &var;
}

int main()
{
    int* p = func();  // OOPS!!!!
                      // p 指向了不合法的地址,这个地址处没有变量存在
                      // p 是一个野指针,保存不合法地址的指针都是野指针

    printf("*p = %d\n", *p);

    *p = 200;   // 改变 func 函数中局部变量 var 的值,是不是非常奇怪???

    printf("*p = %d\n", *p);

    return 0;
}

小结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/738992.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

替代LTC4449高速同步N道沟MOSFET驱动器|具有轨对轨栅极驱动

1. 产品特性 ➢ 15ns 典型传播延迟 ➢ 5ns 高侧/低侧匹配 ➢ 轨至轨栅极驱动 ➢ 自适应死区和直通保护 ➢ 3A 峰值拉电流和 4.5A 峰值灌电流 ➢ 驱动 2 颗 NMOS 组成的半桥 ➢ 欠压保护 ➢ 过热保护 2. 功能描述 PC4449 产品手册 PC4449是一款专为高频率、高效率的应…

教育护眼灯品牌排行有哪些上榜?中国十大教育照明品牌分享

在当前的时代背景下&#xff0c;孩子们的课业负担依然沉重。随着他们年龄的增长&#xff0c;作业量不断增加&#xff0c;对视力的需求也随之上升。加之&#xff0c;现今许多作业需借助电子屏幕完成&#xff0c;孩子们面临视力问题的风险因而愈加提早。家长们逐渐认识到&#xf…

轻量级在线服装3D定制引擎Myway简介

我写的面向web元宇宙轻量级系列引擎中的另外一个&#xff0c;在线3D定制引擎Myway 3D。 用于在线商品定制&#xff0c;比如个性化服装的定制、日常用品&#xff08;如杯子&#xff09;、家装&#xff08;被套&#xff09;等物品的在线定制。 特性列表&#xff1a; 可更换衣服…

什么是中间件?常见中间件有哪些?

中间件是什么 中间件是一种独立的系统软件或服务程序&#xff0c;分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上&#xff0c;管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统&#xff0c;即…

STM32 - LED灯 蜂鸣器

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

adb 查看哪些应用是双开的

adb shell pm list users 得到 这 里有 user 0 ,11,999 其中0是系统默认的&#xff0c;11是平行空间的&#xff0c;999是双开用户 pm list packages --user 999 -3 得到了999用户安装第三方应用的包名 pm list packages --user 11 -3 得到了隐私空间用户安装第三方应用的…

智能客服到个人助理,国内AI大模型如何改变我们的生活?

引言 随着人工智能&#xff08;AI&#xff09;技术的高速发展&#xff0c;AI大模型越来越多地出现在我们的日常生活和工作中。国内的AI大模型在过去几年里取得了显著的进展&#xff0c;不少独创的技术点和实际应用令人瞩目。 那么&#xff0c;国内的AI大模型有哪些独创的技术…

[图解]建模相关的基础知识-17

1 00:00:00,190 --> 00:00:09,650 那么1、2、5这个地方&#xff0c;这几个它都需要修改 2 00:00:09,660 --> 00:00:11,410 都要改成资金管理部 3 00:00:13,340 --> 00:00:15,020 那么违反第三范式 4 00:00:15,030 --> 00:00:19,650 是一个比较严重的问题 5 00:…

苹果Mac系统安装adobe软件“无法打开install因为无法验证开发者”解决方法

对于大部分小伙伴&#xff0c;特别是从事视频后期、设计等专业的人来说&#xff0c;Adobe全家桶系列软件&#xff0c;相信都或多或少用过&#xff0c;比如Photoshop、Premiere、illustrator、Lightroom等等。这些软件不仅支持Windows系统&#xff0c;也完美适配于苹果Mac系统&a…

展讯-GPIO操作

1.修改IO配置 以GPIO92为例 IO配置文件在&#xff1a; bsp/kernel/kernel4.14/arch/arm64/boot/dts/sprd/uis8581e5h10.dts bsp/bootloader/u-boot15/board/spreadtrum/uis8581e5h10/pinmap-sp9863a.c 配置 按上述内容&#xff0c;配置IO口 编译之前查看硬件GPIO&#xff0c…

建议收藏!100款宝藏级AIGC工具分享,70款ChatGPT插件惊艳的开发过程与宏大的商业化愿景

建议收藏&#xff01;100款宝藏级AIGC工具分享&#xff0c;70款ChatGPT插件惊艳的开发过程与宏大的商业化愿景。 不输ChatGPT&#xff1f;整理了100款AIGC神器&#xff0c;打工人速进。 说到AIGC工具&#xff0c;你还是只知道ChatGPT&#xff1f; 实际上&#xff0c;越来越多…

校园设施物联网信息化改造

随着物联网技术的发展越来越成熟&#xff0c;它不断地与人们的日常生活和工作深入融合&#xff0c;推动着社会的进步。其中物联网系统集成在高校实践课程中可以应用到许多项目&#xff0c;如环境气象检测、花卉种植信息化监管、水质信息化监管、校园设施物联网信息化改造、停车…

基于YOLOv8m的水族馆动物识别(附数据集和Coovally操作步骤)

本文主要内容:详细介绍了水族馆动物识别的整个过程&#xff0c;从创建数据集到训练模型再到预测结果全部可视化操作与分析。 文末有数据集获取方式&#xff0c;请先看检测效果 现状 随着水族馆行业的快速发展&#xff0c;对动物识别的需求日益增加。水族馆需要准确识别动物种…

爬虫阶段思考

内容&#xff1a;写这篇文章是因为最近帮同学改了很多的爬虫代码&#xff0c;感触良多。 我用豆瓣为例&#xff0c;并不是不会用别的&#xff0c;而是这个我个人感觉最经典。然后还会写我遇到的一些问题以及解决方法。 首先&#xff0c;我们得先知道怎样爬取。我用的scrapy框…

揭秘shopee、Lazada爆单秘诀:自养号补单策略大公开

在东南亚的电商跨境领域&#xff0c;Shopee和Lazada无疑占据了举足轻重的地位&#xff0c;为印地、马来、台湾、菲律宾、新加坡、泰国和越南等地的消费者提供了丰富的在线购物选择。随着电商竞争的日益激烈&#xff0c;许多商家开始探索各种有效的推广策略&#xff0c;其中&…

Python应用开发——30天学习Streamlit Python包进行APP的构建(8)

st.table 显示静态表格。 这与 st.dataframe 的不同之处在于,这里的表格是静态的:其全部内容直接显示在页面上。 Function signature[source]st.table(data=None) Parametersdata (pandas.DataFrame, pandas.Styler, pyarrow.Table, numpy.ndarray, pyspark.sql.DataFrame,…

哪个牌子充电宝好?好用充电宝排行榜!精选充电宝排行榜

在如今这个科技飞速发展的时代&#xff0c;充电宝已然成为我们日常生活中不可或缺的伴侣。无论是出差旅行&#xff0c;还是日常通勤&#xff0c;我们都离不开它为我们的电子设备保驾护航。然而&#xff0c;面对市场上琳琅满目的充电宝品牌&#xff0c;您是否感到眼花缭乱&#…

【九】【QT开发应用】WebRTC的sigslot源码和使用WebRTC的sigslot使用编写信号槽

WebRTC&#xff08;Web Real-Time Communication&#xff09; 是一个开源项目&#xff0c;提供实时通信能力&#xff0c;广泛应用于视频、音频和数据传输。在WebRTC的实现中&#xff0c;sigslot库用于信号和槽机制&#xff0c;以实现事件驱动的编程模型。 WebRTC的sigslot部分…

[个人感悟] MySQL应该考察哪些问题?

前言 数据存储一直是软件开发中必不可少的一环, 从早期的文件存储txt, Excel, Doc, Access, 以及关系数据库时代的MySQL,SQL Server, Oracle, DB2, 乃至最近的大数据时代f非关系型数据库:Hadoop, HBase, MongoDB. 此外还有顺序型数据库InfluxDB, 图数据库Neo4J, 分布式数据库T…

陀螺仪LSM6DSV16X与AI集成(8)----MotionFX库解析空间坐标

陀螺仪LSM6DSV16X与AI集成.8--MotionFX库解析空间坐标 概述视频教学样品申请源码下载开启CRC串口设置开启X-CUBE-MEMS1设置加速度和角速度量程速率选择设置FIFO速率设置FIFO时间戳批处理速率配置过滤链初始化定义MotionFX文件卡尔曼滤波算法主程序执行流程lsm6dsv16x_motion_fx…