Index:
(new) 指针和数组的区别
(一) 指针的类型, 指针指向的类型.
(二) 指针的加减运算.
(三) 指针与数组.
(四) 数组做函数的形参.
(五) 函数指针.
(六) 指针与数组/数组做函数形参.
(七) C-Style的字符串.
(八) 复杂指针的定义.
(九)C语言中没有引用!
(new) 指针和数组的区别: http://coolshell.cn/articles/11377.html
指针和数组的区别不仅仅是"指针p定义后可以改变其值, 而数组a[]一旦定义后无法改变a的值";
先看下面的代码, 在哪一行会coredown ?
答案是在printf( f.a->s) 挂掉, printf("%x\n", f.a->s)会打印出4,
如果代码中的struct str结构体中的char s[0];改成char *s, 那么代码在if(f.a->s)处就挂掉了, why ?
if (f.a->s) // char* s;
if (f.a->s) // char s[0];
以上两种有什么不同?
用GDB查看汇编代码后发现,:
a. 对于char s[0]来说,汇编代码用了lea指令,lea 0×04(%rax), %rdx
b. 对于char*s来说,汇编代码用了mov指令,mov 0×04(%rax), %rdx
lea全称load effective address,是把地址放进去,而mov则是把地址里的内容放进去。所以,就crash了。
从这里,我们可以看到,访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容(这和访问其它非指针或数组的变量是一样的)
# 对于数组 char s[10]来说,数组名 s 和 &s 都是一样的.
代码二, 哪一行会挂掉?
(new) 指针和数组的区别
(一) 指针的类型, 指针指向的类型.
(二) 指针的加减运算.
(三) 指针与数组.
(四) 数组做函数的形参.
(五) 函数指针.
(六) 指针与数组/数组做函数形参.
(七) C-Style的字符串.
(八) 复杂指针的定义.
(九)C语言中没有引用!
(new) 指针和数组的区别: http://coolshell.cn/articles/11377.html
指针和数组的区别不仅仅是"指针p定义后可以改变其值, 而数组a[]一旦定义后无法改变a的值";
先看下面的代码, 在哪一行会coredown ?
#include <stdio.h>
struct str{
int len;
char s[0];
};
struct foo {
struct str *a;
};
int main(int argc, char** argv) {
struct foo f={0};
if (f.a->s) {
printf("%x\n", f.a->s);
printf( f.a->s);
}
return 0;
}
答案是在printf( f.a->s) 挂掉, printf("%x\n", f.a->s)会打印出4,
如果代码中的struct str结构体中的char s[0];改成char *s, 那么代码在if(f.a->s)处就挂掉了, why ?
if (f.a->s) // char* s;
if (f.a->s) // char s[0];
以上两种有什么不同?
用GDB查看汇编代码后发现,:
a. 对于char s[0]来说,汇编代码用了lea指令,lea 0×04(%rax), %rdx
b. 对于char*s来说,汇编代码用了mov指令,mov 0×04(%rax), %rdx
lea全称load effective address,是把地址放进去,而mov则是把地址里的内容放进去。所以,就crash了。
从这里,我们可以看到,访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容(这和访问其它非指针或数组的变量是一样的)
# 对于数组 char s[10]来说,数组名 s 和 &s 都是一样的.
char a[10] = {0};
char (p)[10] = &a;
printf("%x %x\n", a, p); // 你会发现两个值是一样的
代码二, 哪一行会挂掉?
struct test{
int i;
short c;
char *p;
char s[10];
};
int main(){
struct test *pt=NULL;
printf("&s = %x\n", pt->s); //等价于 printf("%x\n", &(pt->s) );
printf("&i = %x\n", &pt->i); //因为操作符优先级,我没有写成&(pt->i)
printf("&c = %x\n", &am