一、将int强制转换为int指针,将int指针强转换为int

void f(void)
{
int *p = (int*)100; //将int强制转换为int指针
printf("%d\n",(int)p+1); //将int指针强转换为int, 然后+1
printf("%d\n",(int)(p+1)); //将int指针加1(地址增加了4),强制转换为int
} int main(int ac, char **av)
{
f();
return 0;
}

运行结果:

101
104

二、int指针转换为char指针

#include <stdio.h>

int main() {
int a = 8;
int* b = &a;
int *c = (int*)((char*)b + 1);
printf("b = %p, c = %p\n", b, c);
*c = 8;
printf("%d\n", a);
printf("b = %p, c = %p\n", b, c);
printf("%d\n", *c);
return 0;
}

运行结果:

b = 0061FEC4, c = 0061FEC5
2056
b = 0061FEC4, c = 0061FE00
1988445728

运行完第7行:整数a的地址为b = 0x61fec4,内存值为08000000;指针c指向0x61fec5,是a的第二个字节的地址。(小端存储)

运行完第8行,对c指向的内存赋值,这个四个字节被写为 08000000,因此a指向的内存被写为:00000808(b) = 2056(d)。

但由于存储c这个指针的内存正好因此被破坏了,被修改为0061FE00,因此此次输出*c的内容是未知的。

三、数组&指针

1. S6.828

#include <stdio.h>
#include <stdlib.h> void f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i; printf("1: a = %p, b = %p, c = %p\n", a, b, c); c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]); c[1] = 300;
*(c + 2) = 301;
3[c] = 302; // 由于arr[2]等价于*(arr+2), 因而对于2[arr], 其实也就等价于*(2+arr)也是可以通过编译的, 因为+是满足交换律的。
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]); c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]); c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]); b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
} int main(int ac, char **av)
{
f();
return 0;
}

运行结果:

1: a = 0061FEA0, b = 007515B8, c = 0000003D
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0061FEA0, b = 0061FEA4, c = 0061FEA1 Process finished with exit code 0

2. 在 C/C++中,数组和指针是相互关联又有区别的两个概念。

  • 当我们声明一个数组时,其数组的名字也是一个指针,该指针指向数组的第一个元素。我们可以用一个指针来访问数组。data1是一个数组,sizeof(data1)是求数组的大小。

  • data2声明为指针,尽管它指向了数组data1的第一个数字,但它的本质仍然是一个指针。

  • 在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。

#include <stdio.h>
#include <stdlib.h> int GetSize(int data[]){
return sizeof(data);
} int main(void) { int data1[] = {1,2,3,4,5};
int size1 = sizeof(data1);
int* data2 = data1;
int size2 = sizeof(data2);
int size3 = GetSize(data1);
printf("%d %d %d %d\n", size1, size2, size3);
return 0;
}

输出:

64位操作系统

20 8 8 8

四、函数返回局部指针?

  1. 以下代码IDE会告警:Address of stack memory associated with local variable 't' returned。由于局部变量的指针分配在栈上,且函数执行完,栈内存会自动释放,因此reverseLeftWords的返回值总是为NULL,不能得到正确的结果。
char* reverseLeftWords(char* s, int n){
size_t sSize = strlen(s);
if( n == 0 || n >= sSize) return s;
char t[sSize+1];
size_t i;
for(i = 0; i < sSize; i++){
t[i] = s[(i + n)% sSize];
}
t[i] = '\0';
return t;
}
  1. 需要通过malloc来分配堆上内存,返回堆内存地址。
char* reverseLeftWords(char* s, int n){
size_t sSize = strlen(s);
if( n == 0 || n >= sSize) return s;
char* t = (char*)malloc(sizeof(char*)*(sSize+1)); size_t i;
for(i = 0; i < sSize; i++){
t[i] = s[(i + n)% sSize];
}
t[i] = '\0';
return t;
}

深入理解c语言指针与内存的更多相关文章

  1. 2-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...

  2. 深入理解C语言 - 指针使用的常见错误

    在C语言中,指针的重要性不言而喻,但在很多时候指针又被认为是一把双刃剑.一方面,指针是构建数据结构和操作内存的精确而高效的工具.另一方面,它们又很容易误用,从而产生不可预知的软件bug.下面总结一下指 ...

  3. "深入理解C语言" 指针

    本文对coolshell中的"深入理解C语言"这篇文章中提到的指针问题, 进行简要的分析. #include <stdio.h> int main(void){ ]; ...

  4. 深入理解C语言 - 指针详解

    一.什么是指针 C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址.CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位.这里,数据对象是指存储在 ...

  5. 小强版之无码理解C语言指针

     1. 先从普通变量开始   2. 撸完变量撸指针   3. 故事情节进一步发展,此处少儿不宜   4. 奶茶妹妹捉奸,小强死定了   5. 源码欣赏  #include <stdio.h> ...

  6. 13深入理解C指针之---内存管理

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 内存管理对所有程序都很重要,主要包括显式内存管理和隐式内存管理.其中隐式内存管理主要是 ...

  7. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  8. windev中的内存机制及其与C语言中的内存指针相似性(一)

    windev中的内存机制,是初入windev世界必须要越过的一道高山,以下我的理解和经验未必都对,如有错误或遗漏,以后再纠正或补充!另外,以下内容,咱先谈应用,再说对机制的认识和理解. 一.新建表单, ...

  9. C 语言中的指针和内存泄漏

    引言对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧 ...

  10. C语言中的指针和内存泄漏

    引言 对于任何使用C语言的人,如果问他们C语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是 ...

随机推荐

  1. 使用libzip压缩文件和文件夹

    简单说说自己遇到的坑: 分清楚三个组件:zlib.minizip和libzip.zlib是底层和最基础的C库,用于使用Deflate算法压缩和解压缩文件流或者单个文件,但是如果要压缩文件夹就很麻烦,主 ...

  2. js 异步 任务 题目解析(chatgpt bug了?)

    最近遇到一道题如下,求输出结果 感觉还是蛮有意思的,找chatgpt做了一下 我是题 async function async1(){ console.log('1'); await async2() ...

  3. Linux 提权-密码搜寻

    本文通过 Google 翻译 Password Hunting – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充 ...

  4. Java还是C#?我该如何选择?给年轻人的建议...

    一.年轻人应该通吃 其实这不应该是我们真正的主题,而且入了行的也很少会java还是c#这么比,但初学的,java和c#往往就代表了两大流派,java代替了j2ee,c#代替了.net,ok,没有关系, ...

  5. 图书《数据资产管理核心技术与应用》核心章节节选-3.1.2. 从Spark 执行计划中获取数据血缘

    本文节选自清华大学出版社出版的图书<数据资产管理核心技术与应用>,作者为张永清等著. 从Spark 执行计划中获取数据血缘 因为数据处理任务会涉及到数据的转换和处理,所以从数据任务中解析血 ...

  6. 元学习的经典文献:S. Thrun - 1998 - LEARNING TO LEARN: INTRODUCTION AND OVERVIEW

    地址: https://link.springer.com/chapter/10.1007/978-1-4615-5529-2_1

  7. 使用AI模型替代工业仿真过程

    引自: https://www.zhihu.com/question/641951284/answer/3384531468 使用AI模型替代工业仿真,如:CAE,等等,进行仿真环境的求解运算.

  8. GTC 2024 NVIDIA推出的新一代终端智能芯片 —— Jetson Thor

    比较好奇,NVIDIA今年推出的终端芯片Jetson Thor到底是个啥样,毕竟这东西在机器人元年的2024年开始预热宣传,2025年大规模部署,注定是AI领域的一个重要角色. 看完GTC 2024的 ...

  9. NVIDIA公司官宣最新最高性能的GPU芯片及平台 —— Blackwell GPU

    官宣视频: https://www.youtube.com/watch?v=bMIRhOXAjYk 相关: https://baijiahao.baidu.com/s?id=1793921686210 ...

  10. 深度学习框架 MindSpore —— 华为出品的AI计算框架, docker 安装

    深度学习框架  MindSpore  --   华为出品的AI计算框架 官网地址: https://www.mindspore.cn/ 源代码地址: https://gitee.com/devilma ...