C语言学习之 数组,指针,字符串. (一)

此文由来: 是看到野鬼发表的关于C语言知识内容后,一激动,手一痒.回了一篇.惋惜误操做让回复没能保存.
 以后再写就是下面的内容. 野鬼发表的内容 http://www.oschina.net/question/249672_77341

计算机是按照指令进行操做的. C语言与汇编比算高级语言, 但它仍然很"低级".
计算机操做的都是数字, 差异只是 直接操做与间接操做. C仍然能够用这些概念来了解 数组与指针的关系.
好比: int i; i=0; i++; 这3条语句就是属于直接操做, 操做数是 i, 操做的目标也是i;
 另一种 int *p; *p=0; (*p)++; 这3条语句属于间接操做,操做数是p,操做目的(*p);
记住一点,计算机操做的都是数字,也就是 i, 和 p 都是数字, 他们均可以用 printf("%d %d",i,p);来看看具体是什么数字. 这里的差异只是i是一个具体的被操做数,而p只是一个指针,例子中改变的不是p这个数,而是p对应的内容. p所对应的内容是一个int 类型. 因此声明 用的是int *p;
另外,(*p)++; 这个括号不能够少, 不然会变成 p这个指针自增,而后取内容.p自增后指向那里.不肯定,固然是野指针,会出问题的.后话,之后会讨论, 里面有戏法,这个是C的优势.善加利用会有好处. 数组

竟然有人顶个人回帖,这给我增长了信心. 好吧,我会继续完善个人跟帖,帮助与我同一块儿跑线的朋友一块儿学习C语言. 这里声明一点,我也是学习C语言的新手. 跟帖内容是个人理解, 并不是是正确的解释. 具体正确解释仍是请你们听取野鬼的指导文章. 也欢迎给位朋友指出我表述中存在的问题,好帮助我更准确的学习这门语言. 愿我与你们共同进步.
函数

以前表述内容是了解 计算机在处理信息方面采用的方式, 重点仍是"一切都是数字". 
接下来讲说全部变量都有存储位置. 固然,这个是相对来说的.程序编译以及优化过程当中这些概念不必定合适, 可是,对与学习这门语言来讲.仍是认为这句话是对的比较好.(虽然这句话自己就是错的).
 继续给例子, int i; 这个语句声明了一个变量i(我也不知道如何说明这个i, 姑且认为他是一个变量的存储空间).  i就表示一个存储空间, 他的大小 足够放的下一个 int 内容. int 是什么? 是一种类型.这些概念以前有讲过, 能够看以前内容加深理解.  这里能够大致上理解为 "宽度" 若是以8位表示一个字节的话, char 类型就是占用一个字节, int 类型占用 sizeof(int) 个字节, sizeof(int) 是什么?  sizeof 是操做符. 用来返回 目标 占用的存储空间大小, 以字节为单位表示. sizeof(char) 返回确定是1. 这个就叫标准. sizeof(int) 会返回什么? 标准中没规定具体数值. 根据编译器以及对编译目标平台来决定. sizeof用来干什么? 备用. 
以后说说 数组.  char a[9];  这个语句就是定义一个数组. 数组名是a,  数组大小是9个char 大小. 占用空间 计算方式为 9*(sizeof(char)). sizeof(char) =1 (这个是规定). 因此 9*sizeof(char) =9; 因此 char a[9]  会占用9个字节的存储空间. char a[8] 会占用8个字节的存储空间. 因此 char a[9] 是用来声明 a 地址内会有 9 个字节的空间能够用以程序使用.  short a[9] 会有 18个字节的空间, 此时a 的大小有 9*sizeof(short) = 18.  sizeof(short) = 2 也是规定.   在这里记住一点, a 也是有数值的. 全部操做都是用来操做数字的. a能够理解为一个 存储空间的首地址. 一切皆为数字. 学习

再来讲一下指针与数组的关系. 
 看例子. char a[9]; char *pa; pa=a; 这3条语句比较好理解. 首先 声明了一个 大小为 9*sizeof(char) 的存储空间, 入口地址是 a , 以后声明了一个 存储空间, 存放pa, 它是一个指针.大小是指针的存储空间--> sizeof(void *);  类型不一样啊. 管他呢.  指针大小在同一平台下是 不变的.   最后 pa=a ; 意思是将第二条 申请的空间内容 存储成 a 的值. a 是什么?  a其实就是一个数字, 是 数组存储位置的首地址.  下面要说的就是神奇的地方. 指针运算. 优化

变戏法, 指针运算
依然看上面的例子.  a 表示一个长度为9的存储空间, a也是个数字, a也能够表示为9个存储空间的首地址. 由此能够理解为, 数组,是一段连续空间的表示形式. 数组名是空间首地址.
在这里须要引入一个概念, 数组指针, 数组指针是区别与指针数组的. 数组指针其实是一个指针, 声明的时候会分配一个存储空间给它,分配给他的存储空间长度为 指针的长度, 内容是一段指向连续空间的存储空间首地址.
先来讲一下指针,数组之间的魔法. 例子中 pa 是一个指针, 类型是 char . a 是一个数组, 类型是 char 的数组,  pa=a; 后,会发生什么呢, pa 是一个char 类型的指针, 指向的内容类型也就是一个 char, 因此 *pa 就是一个char 类型. 来看下:
char a[9]="9742"; /*声明并赋值*/ 
char *pa;
pa=a;/*这段能够简单写成 char *pa=a; 声明并赋值*/
printf("%c\n", *pa);/* 这段会输出 字符 9 并换行. */
pa++; /* 指针运算,自增 */
printf("%c\n", *pa);  /* 这段会输出字符 7, 并换行*/ .net

其实,上面这段是一个小魔术, 不过这个魔术会在C语言中随处可见. 缘由很简单. C代码当中,处处都是指针. 为了代码的优美, 指针遍及各个角落, 这样的魔术也遍及个个角落. 相对于数组, 指针能够经过修改一个数字来操做改变后的内容,相对于数组只能经过下标的不一样来修改要方便的.
为加深印象. 查看下面的代码.
 short a[9]; /*声明数组*/
a[0] = 9;
a[1] = 1;
a[2] = 7;
a[3] = 4;
a[4] = 8;
short *pa; pa=a; 
printf("%d\n", *pa);
pa++;
printf("%d\n", *pa);
printf("%d\n", *(pa+1)); 
printf("%d\n", *(pa+2));  
固然,在这里, 也能够用printf("%d\n", *(a+1)); 来实现第二个输出语句所实现的目的. 可是却没办法执行 a++; 这样的操做.  或许会有疑问, 既然能够*(a+1) 为何还要 *(pa+1);
这就引出更多的内容. tyepdef 指针

我不是万恶之源,我只是一粒沙.我是 typedef
为何要这么说. 由于我不是让代码变得 凌乱的 罪魁祸首, 我只是一个让一切变得好起来的帮手.我是typedef. 请好好待我. get

仍是例子:
typedef char ta[5];/* 一个5字节的连续空间 */
int fa() { 
ta a;
return 0;
}
定义了一个函数 fa, 返回类型是 int ,  里面声明了一个变量 a;
a 其实就是一个 数组,  和 char b[5]; 效果是同样的. 这没什么好稀奇的.
使用的时候能够 a[0],a[1],a[2]; 相似的, char b[5]在使用的时候也能够是 b[0],b[1],b[2],b[3] 编译器

ta a[3];  a[3] 的效果和 char b[3][5]; 是同样的. 二维数组. 没错.就是他, 能够更简单一些.
使用的时候, 能够 a[0][0]... a[2][4]; 是这样. 那有什么优点呢?  魔术,魔法. 指针是很神奇的东西. io

相关文章
相关标签/搜索