C/C++教程

【养成记】嵌入式挑战第7天,C语言中的指针:一级指针简介

本文主要是介绍【养成记】嵌入式挑战第7天,C语言中的指针:一级指针简介,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

课程章节:

  • 课程名称:物联网/嵌入式工程师
  • 章节名称:第2周之第三讲 1-6 C语言中的指针:一级指针简介
  • 讲师姓名:大白老师

课程内容:

C语言中的指针

一级指针简介

数据类型

int m = 20;
int *p = &m;
指针变量p本身的数据类型:int *
指针变量保存的对象的数据类型: int

大小端模式

不同系统使用的CPU不同,对数据的存储形式也有不同,成分为以下两种。

大端模式: ARM, 摩托罗拉

小端模式: intel,MIPS

=======================================================

大端模式:内存的高地址存储数据的低位,内存的低地址存储数据的高位。
(低地址存高位---低对高)

小端模式:内存的低地址存储数据的低位,内存的高地址存储数据的高位。
(低地址存低位---低对低)
        
         int x = 0x12345678;   //1个十六进制数 = 4个二进制数
                               //1bytes = 8个二进制数
                                                   // 1bytes = 2个十六进制数
     // 123   左边为高位,右边为低位。
            小端模式                 大端模式
低地址
0xdff30      0x78                     0x12                <------
0xdff31      0x56                     0x34
0xdff32      0x34                     0x56
0xdff33      0x12                     0x78
高地址         

指针的结论

在32bit的操作系统中,所有类型的指针变量都是4bytes. [因为地址为4bytes]
在64bit的操作系统中,所有类型的指针变量都是8bytes. [因为地址为8bytes]

代码示例

#include <stdio.h>

int main()
{
    char *x;
    short *y;
    int *z;

    printf("sizeof(x) = %ld\n",sizeof(x));
    printf("sizeof(y) = %ld\n",sizeof(y));
    printf("sizeof(z) = %ld\n",sizeof(z));

    return 0;
}

不同类型的指针变量,对C语言中的同一块内存进行读取的时候,每次读取的字节数不同。

读取为指针变量 + *,剩下数据类型的大小

int a = 0x12345678;  (ubuntu默认小端模式)
   
低地址
0xdff00                0x78 
0xdff01                0x56
0xdff02                0x34 
0xdff03                0x12
高地址

char *p = (char *)&a;
short *q = (short *)&a;
int *m = &a; 
 
*p; //读取变量a的1bytes数据
*q; //读取变量a的2bytes数据
*m; //读取变量a的4bytes数据

代码示例:

#include <stdio.h>

int main()
{
    char *x;
    short *y;
    int *z;
    int t = 0x12345678;

    x = (char *)&t;
    y = (short *)&t;
    z = &t;

    printf("*x = %#x\n",*x); //输出十六进制数
    printf("*y = %#x\n",*y);
    printf("*z = %#x\n",*z);
}

在32bit的操作系统中,不同类型的指针变量每次的移动大小不一样。

每次移动的大小为指针变量 + *,剩下数据类型的大小

int a = 0x12345678;
char *p = (char *)a;
short *q = (short *)a;
int *m = a; 

p++; //每次移动1bytes的大小
q++; //每次移动2bytes的大小
m++; //每次移动4bytes的大小

代码示例

#include <stdio.h>

int main()
{
    char *x;
    short *y;
    int *z;
    int t = 0x12345678;

    x = (char *)&t;
    y = (short *)&t;
    z = &t;

   // printf("*x = %#x\n",*x); //输出十六进制数
   // printf("*y = %#x\n",*y);
   // printf("*z = %#x\n",*z);

    printf("&t = %p\n",&t);
    printf("x = %p\n",x);
    printf("y = %p\n",y);
    printf("z = %p\n",z);

    printf("======================\n");

    x++;
    y++;
    z++;

    printf("&t = %p\n",&t);
    printf("x = %p\n",x);
    printf("y = %p\n",y);
    printf("z = %p\n",z);

    return 0;
}

学习笔记:

课后练习

练习1

定义一个数组
int a[5] = {0};
要求大家从键盘上输入数据给数组赋值。
然后定义一个指针int *p_max要求它保存最大值的地址。
然后通过*p_max输出最大值。

代码示例:

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int *p_max = 0;

    for(int i = 0; i < sizeof(a)/sizeof(a[0]); ++i) 
    {
        scanf("%d",&a[i]);
    }

    p_max = &a[0];

    for (int i = 0; i < sizeof(a)/sizeof(a[0]); ++i)
    {
        if (a[i] > *p_max)
        {
            p_max = &a[i];
        }
        printf("%d ",a[i]);
    }

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

    return 0;
}

练习2

unsigned int data = 0x11223344;
unsigned short *q = NULL;

unsigned short t1 = 0;
unsigned short t2 = 0;

(1)要求指针q保存data的地址.
(2)要求利用q读取data的低2个字节赋值給t1 ===>0x3344
   要求利用q读取data的高2个字节赋值給t2 ===>0x1122
(3)输出t1和 t2 的和与差

代码示例:

#include <stdio.h>

int main()
{
    unsigned int data = 0x11223344;
    unsigned short *q = NULL;

    unsigned short t1 = 0;
    unsigned short t2 = 0;

    // (1)要求指针q保存data的地址.
    q = (unsigned short *)&data;
    /*
    (2)要求利用q读取data的低2个字节赋值給t1 ===> 0x3344
       要求利用q读取data的高2个字节赋值給t2 ===> 0x1122
    */ 
    t1 = *q;
    t2 = *(q+1);
    printf("t1 = %#x\n",t1);
    printf("t2 = %#x\n",t2);
    // 输出t1和 t2 的和与差
    printf("t1 + t2 = %#x\n",t1+t2);
    printf("t1 - t2 = %#x\n",t1-t2);

    return 0;
}

课程评价:

通过对一级指针的学习,明白了大端小端的内存地址的存储方式有了一定了解,还有指针类型的不同存储的大小也不同。

这篇关于【养成记】嵌入式挑战第7天,C语言中的指针:一级指针简介的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!