原创作者: simohayha
阅读:6128次
评论:2条
更新时间:2011-05-26
指针是c的灵魂,俺这里只能抛砖引玉了.
1 首先,数组名不能当作赋值对象,比如下面的代码:
2 下面阐述一下,指针和数组各自是如何访问的:
编译器符号表有一个符号 s 地址为 1234,然后首先取i的值,把i和1234相加,然后取出(i+1234)的内容付给c.
编译器符号表有一个符号s,他的地址为1234,然后取地址1234的内容,就是'5678',然后把i和5678相加,然后取出(i+5678)的内容付给c.
大家可以看下下面的这个程序:
呵呵,s和s[0] 的地址竟然不一样。
3 定义指针时编译器并不为指针所指向的内容分配空间,它只分配指针本身的空间,除非在声明的同时付给指针一个字符串常量初始化。比如:
可是只有对字符串常量才是如此,其他的类型都会出错。
4 数组和指针的相同点。
。表达式中的数组名(不同于声明)被编译器当做一个指向数组第一个元素的指针。
。下标总是和指针偏移量相同,a[i]总是被编译器改写成*(a+i)这种形式来访问。(比如:a[6]和6[a]是一样的)
。在函数参数的声明中,数组名被编译器当做一个指向数组第一个元素的指针
可以看下下面的代码的输出。
为什么c要做成这种呢,其实很简单,就是在c中调用函数的时候会把实参进行拷贝,而如果实参是数组的话,拷贝的开销太大,所以不如指针方便.
呵呵,这边多维数组没有涉及到,不过多维数组只要紧记不过是数组的数组罢了.
1 首先,数组名不能当作赋值对象,比如下面的代码:
char *s="abc"; char *s1="bcd"; s1=s; printf("%c\n",s1[0]);可以正常运行,如果把 这边的指针变为数组就会出错。
2 下面阐述一下,指针和数组各自是如何访问的:
char s[]="abc"; c=s[i];
编译器符号表有一个符号 s 地址为 1234,然后首先取i的值,把i和1234相加,然后取出(i+1234)的内容付给c.
char *s="abc"; c=s[i];
编译器符号表有一个符号s,他的地址为1234,然后取地址1234的内容,就是'5678',然后把i和5678相加,然后取出(i+5678)的内容付给c.
大家可以看下下面的这个程序:
#include <stdio.h> void main() { char *s="abc"; char s2[]="789"; printf("%d\n",&s); printf("%d\n",&s[0]); printf("%d\n",&s2); printf("%d\n",&s2[0]); }
呵呵,s和s[0] 的地址竟然不一样。
3 定义指针时编译器并不为指针所指向的内容分配空间,它只分配指针本身的空间,除非在声明的同时付给指针一个字符串常量初始化。比如:
char *s="abc";
可是只有对字符串常量才是如此,其他的类型都会出错。
4 数组和指针的相同点。
。表达式中的数组名(不同于声明)被编译器当做一个指向数组第一个元素的指针。
。下标总是和指针偏移量相同,a[i]总是被编译器改写成*(a+i)这种形式来访问。(比如:a[6]和6[a]是一样的)
。在函数参数的声明中,数组名被编译器当做一个指向数组第一个元素的指针
可以看下下面的代码的输出。
#include <stdio.h> void f(char s[]); void g(char *s); char s2[4]="789"; void main() { printf("%d\n",&s2); printf("%d\n",&(s2[0])); f(s2); g(s2); } void f(char s[4]) { printf("%d\n",&s); printf("%d\n",&(s[0])); } void g(char *s) { printf("%d\n",&s); printf("%d\n",&s[0]); }
为什么c要做成这种呢,其实很简单,就是在c中调用函数的时候会把实参进行拷贝,而如果实参是数组的话,拷贝的开销太大,所以不如指针方便.
呵呵,这边多维数组没有涉及到,不过多维数组只要紧记不过是数组的数组罢了.
2 楼 whking2003 2012-07-25 21:56
http://dolive.iteye.com/blog/394706
这个帖子解释了指针的基本概念。这个人的空间中还有几篇写指针的文,比较深入一点的。写的很不错,建议都看看。
但是,要真正理解指针和数组,最好有汇编的知识,理解变量的本质,明白“赋值”是在做什么,理解偏移量的概念,理解内存分配中“堆”和“栈”的概念。
1 楼 zhao15833999732 2010-10-07 20:37