“->”是一个整体,它是用于指向结构体子数据的指针,用来取子数据。
p=p->next ,意思是将p指向的一个结构体实例中的自数据next赋值给p
指针是一个地址,而指针变量是存放地址的变量
&a,返回a指向的内存的地址
int *p声明p为一级指针变量
另外*的用法:取值操作,即*p指针p保存的地址所对应的值
int **p声明p为二级指针变量,二级指针存储一级指针的地址
int &是定义引用,而int *是定义指针
引用本质上是常量指针
int a = 1
int *p = &b
int &b = a
变量名不占用内存,编译时
结构体:一种数据类型
struct tag {
int a;
char b;
} ;
struct tag t1,t2; //不要忘记struct
struct tag{
}t1,t2; //与上面效果相同
tag为结构体标签,abc为结构体变量,这两个都可有,也可以没有
结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针
typedef struct tag{
…
}abc;
加上typedef后,abc就不是一个对象,abc=struct tag,表示一个类型,即abc t1,t2;
即:typedef为现有类型创建别名
也可以直接定义typedef struct _dictobject PyDictObject,将_dictobject起别名为PyDictObject
条件编译
#ifdef 判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef 与#ifdef相反,判断某个宏是否未被定义
#elif 相当于C语法中的else-if
#else 相当于C语法中的else
#endif #if, #ifdef, #ifndef这些条件命令的结束标志
宏
带参数的宏:#define 标识符(x1,x2,……,xn)
#define add(x1,x2) (x1+x2)
add(1,2)
类似于lamda函数,但有函数名,可调用
宏的与函数对比的优点:宏是在预处理阶段执行,函数调用则会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。其次,函数的参数必须被声明为一种特定的类型,而宏是与类型无关的
register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。
size_t它是一种“整型”类型,里面保存的是一个整数
size_t的全称应该是size type,是“一种用来记录大小的数据类型”
size_t
size=
sizeof
(i);
//用sizeof操作得到变量i的类型的大小
sizeof()返回内存大小(对应python源码中的allocate)
strlen()返回长度,个数(对应python源码中的ob_size)
void *memset(void *s, int c, unsigned long n);
memset函数:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据对象进行初始化。
PyObject_GC_New与malloc,除了分配内存外,还与垃圾回收机制相关