c 的那点就在指针,它给user 的权限太大。
以一个例子开始:
strcut test_t
{
int a;
char b;
int c;
};
char *p; int *p1; struct test_t *p2;
printf("%d",sizeof(p))
==> 输出为 4
printf("%d",sizeof(*p)
==> 输出为 1
printf("%d",sizeof(p1))
==> 输出为 4
printf("%d",sizeof(*p1)
==> 输出为 4
printf("%d",sizeof(p2))
==> 输出为 4
printf("%d",sizeof(*p2)
==> 输出为 12
从上面的例子能说明神魔: 1. 指针本身占 4个字节。 *p 指的是指向的地址的 变量的长度,所注意才有1 到3 的不同
进阶: char **pp
printf("%d %d %d %d\n",sizeof(char *),sizeof(**pp),sizeof(*pp),sizeof(pp))
输出是什么?
4,1,4,4
这是应为 char * 时表示指针 4 个字节,**pp 表示指针指向的值 char 为1,*pp 表示地址值 4,pp 同样是地址值 4
char *p = (char *)malloc(4 *4);
char **p2=(char **)malloc(4*4)
这两个有什没不同?
答案是不同的, 因为双指针是一个 地址 这个地址中存放的是一个指针的地址值。 因此他的初始化就必须malloc 两次。
*p2=malloc(n); *(p2+1)=malloc(n); .... *(p2+3)=malloc(n);
如此这样,还不如试着理解一下指针这个东西。 指针无非有两层含义,一本身是一个四字节的变量。其次他需要指向一块地址。 这样是不好理解了,双指针就是 指向指针的指针,那么 他自己是不有一个地址,其次他要指向一个地址, 双指针指向的是一个指针地址,要想用这个指针是不又得给他指向一个地址。
因为指针只管指向一个地址,那他指向的地址 就需要自己来解析。所以我们的了解各类型变量名的含义才能更好的用指针;
数组: char arr[12] --> arr 表示一个地址值 和 &arr &arr[0] 是一个地址,弹药搞清楚arr[0..n] 就不是地址值了,那就是char 的变量值 一旦声明 地址就确定了就不能改变了 所以我们可以看作一个指针常量。所以数组直接复制是错的 相当于改变指针常量。
int arr[12] --> arr 也表示一个地址和&arr &arr[0] 是一个地址
变量:char a --> a 就表示 一个char 值,&a 是地址
int a -->a 就表示 一个char 值,&a 是地址
char *p --> p 表示是地址值,*p 表示 char 值
结构体: struct test a --> a 表示一个变量名 不是地址,&a 就是结构体的 的第一个变量的值, 因为 结构体有对其问题,虽然他的整体地址是连续的但由于对其问题 导致内部变量地址不是连续的。 那么直接 %d %d a a+1 来打印 test a 的第一各变量 第二变量可以吗? 不可以 因为 a+1 表示 的步长不是以 而是 sizeof(struct test), 所以又喝多地址 +1 的步长 要搞清楚
指针: char *p --> p 表示的就是地址。
notes: 两个数组直接复制可以吗? 例如 char a[12]="test", c+har b[12] char c[8]; b=a, c=a?
这样有问题吗? 不行因为c 中数组一旦申明就是一个确定的不可改变的地址指针常量,所以c 就规定不能 数组直接赋值?
那么两个struct 变量之间呢,因为他的名字不是一个地址 而他的地址又是连续的。在不含指针成员变量的结构体 是可以直接赋值的, 如果有指针成员变量就不可以了,一位如果a.c malloc 让后把a 赋给另一个结构体变量。那么 a.c free 后另一个变量的c 指针地址也free 了 这样一来就带来一些列的麻烦,所以c 也规定结构体不可以直接赋值。
只要是地址 用memcpy 不论是什么类型都可以 复制。