CSDN在线讲堂-》玩转C指针 学习笔记
玩转C指针
前段时间听了CSDN在线讲堂的嵌入式C学习关于指针的课,下面是我的学习笔记,记下了我认为比较重要的知识点,笔记并不全面,就算是学习的tips。
1.看下面的代码:
#define INT_T int* typedef int* int_t; void main(){ INT_T p1,p2; int_t q1,q2; }
这两种定义方式是有区别的。
第一种的情况是,在编译之前,编译器用int*替代代码中的INT_T,所以INT_T p1,p2;相当于int* p1,p2;所以p1为指向int型的指针,p2为int型变量。
第二种情况,typedef将int*定义为一种类型,叫int_t,所以q1、q2都为指向int型的指针。
引深:
在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。
typedef 声明,简称 typedef,为现有类型创建一个新的名字。比如人们常常使用 typedef 来编写更美观和可读的代码。所谓美观,意指 typedef 能隐藏笨拙的语法构造以及平台相关的数据类型,从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭示 typedef 强大功能以及如何避免一些常见的陷阱。
2.编程建议:
所有自定义的类型(如用typedef定义的类型)的名字加_t后缀,便于程序阅读。
3.看下面代码:
int main(){ int **p; int a; *p=&a; return 0; }
这段代码编译能够通过,但会引发段错误。原因在于,**p指向了未知的内存空间,造成了段错误。**p为二级指针,它存储指针*p的地址,*p指向int型变量a。但此处*p并没有声明或定义,所以是未知的、不可访问的内存空间,而**p指向了它,造成了段错误。
指针必须指向可访问、已知的内存空间。
上面的代码改成下面的就正确了:
int main(){ int **p; int *q; int a; q=&a; p=&q; return 0; }
在实际的编程中一定要注意这样的问题,确保指针指向可访问、已知的内存空间,否则会造成不易察觉的错误。
3.函数的接口要保持稳定。
4.在C语言中直接改变函数的参数的值对调用者来说是无效的。若需要改变形参的值,指针便会派上用场,或C++中的引用。
引深:
C语言中函数调用机制决定了直接改变参数的值对调用者无效。因为调用函数会开辟新的空间,在调用函数内声明定义的变量仅在此函数内有效,当函数调用结束时编译器自动释放了这段空间。而此函数的形参仅仅是调用者传递的实参的副本,对副本值的改变不会影响到调用者中实参的值。在C语言中,参数相当于局部变量。如果使用指针传递,则调用函数中的形参是要改变值的对象的地址的副本,对此副本指向空间的内容的改变将影响到调用者中对象的值。C++中的引用是指向变量的别名,注意其与指针的区别。
5.看下面的代码:
int *func(void){ int b=200; return &b; }
此代码片段是错误的。根据上面说的函数的调用机制,变量b为局部变量,其内存空间在函数调用完之后便被编译器释放了,所以返回的地址指向了未知、不可访问的内存空间,造成段错误。
引深:
函数可以返回全局变量指针、静态变量指针、malloc分配的内存块的指针,不可以返回局部变量的指针。
6.看以下代码:
void main(){ int *p; char *q; p++; //向后移动4个字节 q++; //向后移动1个字节 }
指针变量累增,累增的字节数为其所指向对象占用空间的大小。
struct Test *sp; sp++; //向后移sizeof(struct Test)个字节
7.看下面的代码:
int main(){ int a=0x12345678; printf("%x/n",*((char *)&a)); //显示结果为:78 printf("%x/n",*((short *)&a)); //显示结果为:5678 printf("%x/n",*((int *)&a)); //显示结果为:12345678 }
啊,ubuntu下的画图软件openoffice.org图画不能保存为jpg文件,只好自己说了。在内存空间中,a占用4字节,char为1字节,short为2字节。在第一个输出中,将&a强制转换为指向char类型的指针,所以只显示&a指向地址后1字节中的内容,即78.同理,第二个输出为5678。第三个自然是12345678.此例说明了指针必须指定其指向变量类型的意义。
8.检验系统默认为大端法还是小端法的函数
int test_endian(void){ int a=0x12345678; return *((char *)&a)==0x78; }
返回值中使用了逻辑表达式,非常的简洁。
希望上述的笔记对大家有帮助。
CSDN在线讲堂-》玩转C指针 学习笔记相关推荐
- 数组存储与指针学习笔记(三)指针与数组
嵌入式C语言学习进阶系列文章 GUN C编译器拓展语法学习笔记(一)GNU C特殊语法部分详解 GUN C编译器拓展语法学习笔记(二)属性声明 GUN C编译器拓展语法学习笔记(三)内联函数.内建函数 ...
- 重读经典:C和指针学习笔记
重读经典:<C和指针>学习笔记 <C和指针>. <C专家编程>. <C陷阱和缺陷>并称c语言三本经典著作,笔者在许多年前囫囵吞枣读完了这三本经典,然后把 ...
- 变量和指针——学习笔记
数据和地址 变量绑定了一块内存,一块内存1-4个字节 一个变量:多个地址所标记的内存段,多个地址! 内存段的第一个地址叫首地址,一般简称为地址. 普通变量的定义 指针变量 int* p; 定义了一个指 ...
- 指针学习笔记(更新中)
1.指针也分类型,有啥类型的数据,就有啥类型的指针.eg:int p; int *p; 2.指针存放的数据的地址,所以指针变量会有eg: int var_runoob = 10; int *p; // ...
- C++函数指针 学习笔记
无参函数指针的声明和调用 #include <iostream> int func1() {return 1; } int main() {int (*ptrFunc)();ptrFunc ...
- zxd指针学习笔记1
1.什么是指针? int *p; 如上代码,表示我们定义了一个指针变量p,p所指向的数据类型是int类型的. int a = 100; int *p = &a; 如上代码,表示我们定义了一个i ...
- 【汇编语言】清华大学学堂在线《汇编语言程序设计》课程学习笔记
0 前言 全是基于x86系列处理器 1 寄存器与存储器的区别 2 汇编程序员眼中的系统结构 指令寄存器 PC(Program Counter) 指向下一条指令的地址 16位 CS:IP 32位 EIP ...
- C语言学习笔记——指针章节
学习小结 c语言指针学习笔记汇总 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//指针 //在计算机科学中,指针是编程语言的一个对 ...
- Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取
Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7x86 + ...
最新文章
- Android逆向之路---Faceu的登录功能真的只提交了用户名和密码吗
- c语言实现数码管显示qq号,各位大神,如何用C语言实现在数码管上实现1234同时亮...
- Git工作流程和rebase与合并问题
- 关于面试题的一些题型解析
- java创建描述文件,IT技术交流:Java 轻量级整合开发
- Ubuntu18.04 安装 gnuplot
- 颜宁:批评一下当年的「颜宁同学」
- 记录一种多个按钮中每次只能选中一个的实现方式
- iPhone SE 2生产无限期推迟,苹果决定推迟3月份产品发布会
- 谁说 Java 不能用来跑 Serverless?
- python数学建模可视化,[Python与数学建模-数据处理与可视化]-3数据处理工具Pandas...
- 数学建模——五步方法
- kettle数据清洗
- 《正见——佛陀的证悟》读后感
- Appium+python自动化(七)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 上(超详解)...
- 八皇后问题 回溯法
- 网络渗透中的指纹识别
- 解决ppt的页码不显示的问题
- linux 脚本usleep,Linux的sleep()和usleep()的使用
- MySQL Status意义