> 文章列表 > C/C++|物联网开发入门+项目实战|指针|嵌入式C语言高级|C语言内存空间的使用-学习笔记(9)

C/C++|物联网开发入门+项目实战|指针|嵌入式C语言高级|C语言内存空间的使用-学习笔记(9)

C/C++|物联网开发入门+项目实战|指针|嵌入式C语言高级|C语言内存空间的使用-学习笔记(9)

文章目录

  • 2-3 : C语言内存空间的使用
    • 指针概述
      • 示例:
    • 指针+修饰符
    • 指针+运算符
      • 示例
      • 示例1
    • 多级指针
      • 例子
      • 省略argc(个数)的常用写法:

参考:
麦子学院-嵌入式C语言高级-内存空间

2-3 : C语言内存空间的使用

指针概述

内存类型资源地址、门牌号的代名词
指针:地址的代名词
指针变量:存放指针这个概念的盒子
*P
char *p
*p;
C语言娟译器对指针这个特殊的概念,有2个疑问?
1、分配一个盒子,盒子要多大?
在32bit系统中,指针就4个字节
2、盘子里存放的地址所指向内存的读取方法是什么?
3、指针指向内容空间,一定要保证合法性。

示例:

#include <stdio.h>int main()
{int *p1;char *p2;printf("the p1 is %u,p2 is %u\\n",sizeof(p1),sizeof(p2));return 0;}返回值(64位系统):
```bash
E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
the p1 is 8,p2 is 8

在这里插入图片描述

读内存空间(int):

#include <stdio.h>int main()
{int a = 0x12345678;int *p1;p1 = &a;printf("the p1 is %x\\n",*p1);return 0;}
// 返回值
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// the p1 is 12345678

读内存空间(char):

#include <stdio.h>int main()
{int a = 0x12345678;char *p1;p1 = &a;printf("the p1 is %x\\n",*p1);return 0;}
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// 2.c: In function 'main':
// 2.c:8:8: warning: assignment from incompatible pointer type [enabled by default]
// the p1 is 78

浮点数的存储(形式非常特殊)
显示方法1:

#include <stdio.h>int main()
{float a = 1.2;int *p;p = &a;printf("the p1 is %x\\n",*p);return 0;}
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// 2.c: In function 'main':
// 2.c:8:7: warning: assignment from incompatible pointer type [enabled by default]
// the p1 is 3f99999a

显示方法2:

#include <stdio.h>int main()
{float a = 1.2;unsigned char *p;p = &a;printf("the p1 is %x\\n",*p);return 0;}
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// 2.c: In function 'main':
// 2.c:9:7: warning: assignment from incompatible pointer type [enabled by default]
// the p1 is 9a

注意:如果用char *p,会打印符号位,导致显示为:the p1 is ffffff9a。

指针+修饰符

const
常量,只读【不能变】。
在这里插入图片描述

内存用性:
1、内存操作的大小
2、内存的变化性,可写可读

const char *p 【推荐】 字符串常量 p是门牌号
char const *p 同上,

char *const p【推荐】 硬件资源 LCD 指向固定地址,内容可以刷新
char *p const 同上,

const char *const p ROM

示例:

#include <stdio.h>int main()
{char *p = "hello world!\\n";char buf[] = {"hello world!\\n"};char *p2 = buf;printf("the one  is %x\\n",*p);*p2 = 'a'; //不合法,会出现段错误printf("%s\\n",p2); //无输出return 0;}

正确的写法应该是:
const char p = “hello world!\\n”;
此时
p2 = 'a’编译器提示错误:

E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
2.c: In function 'main':
2.c:11:5: error: assignment of read-only location '*p'

volatile
防止编译器优化指向内存地址,每次都要强制更新或者执行地址所指的值
volatile char *p
*p== 0x10
while(p == 0x10 );
xxx
typedef
char *p;
什么类型,变量名称;
char *name_t; name_t是一个指针(存储地址的盒子),指向了一个char类型的内存
typedef char *name_t; name_t是一个指针类型的名称(别名),指向了一个char类型的内存

name_t abc;

指针+运算符

++,–,+,-

int *p = xxx [0x12]

p+1 [012+1(sizeof(*p))] +1是指向下一个单位,操作的是单位。
指针的加法运算,实际上加的是一个单位,单位的大小可以使用sizeof(p[0])

int *p p+1
char *p p+1

p++ p-- 更新地址
[]
变量名[n] p+n等到地址, p[n]自动将该地址的内容取出来
n ID 标签
地址内容的标签访问方式,取出标签里的值。

示例

#include <stdio.h>int main()
{int a = 0x12345678;int b = 0x99991199;int *p1 = &b; //指针与地址类型一致char *p2 = (char *) &b; //如果不强制转换,编译器会报警告,变量类型与指针不一样printf("the p1+1 is %x ,or is %x, *p1+1 is %x\\n",*(p1+1),p1[1],*p1+1);printf("the p2+1 is %x \\n",p2[1]);return 0;}
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// the p1+1 is 64fe14 ,or is 64fe14, *p1+1 is 9999119a
// the p2+1 is 11

与教程有差异,没有得到预想的结果,见图:

另外对于const的缺陷,编译器也做了优化,不再能够修改,如一下代码:

#include <stdio.h>int main()
{const int a = 0x12345678; //编译器告知结果int b = 0x11223344;//a = 100; //2.c:8:5: error: assignment of read-only variable 'a'int *p = &b;//*(p+1);p[1] = 0x100;printf("the a is %x\\n",a);return 0;}
// p[1] = 0x100未能实现
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// the a is 12345678

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

const的详细解释:可参考C语言中的const
P+1与*(P+1)的延伸可参考:关于C语言中二维数组的P+1与*(P+1)个人浅见

逻辑操作符>= <= == !=

1、跟一个特殊值进行比较,0x0,地址的无效值,结束标志。
if (p==0x0);
建议用NULL进行比较。
2、指针必须是同类型的比较才有意义
char *
int *

示例1

#include <stdio.h>int main()
{int a = 0x12345678; //编译器告知结果int b = 0x99991199;int *p1 = &b;char *p2 = (char *)&b;if(p1 >= p2){printf("===========\\n");}// printf("the a is %x\\n",a);return 0;}
// E:\\temp>cd "e:\\temp\\" && gcc 2.c -o 2 && "e:\\temp\\"2
// 2.c: In function 'main':
// 2.c:12:11: warning: comparison of distinct pointer types lacks a cast [enabled by default]

多级指针

int p;
存放地址的地址空间,
如:char p 描述内存与内存之间的线性关系,

p[0] p[1] p[n]
在这里插入图片描述

p[m]==NULL —>二维空间结束了(结束标志)

例子

#include <stdio.h>int main(int argc,char argv)
{int i;for(i = 0;i < argc;i++){printf("the argv[%d] is %s\\n",i,argv[i]);}return 0;}
// gcc 2.c -o 2
// E:\\temp>2 123 456
// the argv[0] is 2
// the argv[1] is 123
// the argv[2] is 456

省略argc(个数)的常用写法:

在这里插入图片描述

#include <stdio.h>int main(int argc,char argv)
{int i = 0;while(argv[i] != NULL){printf("the argv is %s\\n",argv[i]);i++;}return 0;}
// E:\\temp>2 123 456
// the argv is 2
// the argv is 123
// the argv is 456