指针与数组的缘定今生
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针与数组的缘定今生相关的知识,希望对你有一定的参考价值。
在讲指针时,我先讲讲我使用的编译器gcc。我是比较喜欢在linux上写C语言的。
gcc最基本的用法:
-c:只编译,不链接成可执行文件编译器只是由出入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的之程序文件
-o:确定输出文件的名称为out_filename,同时这个名称不能和源文件同名,如果不给这个选项,gcc就要给出预设的可执行文件a.out
-g:产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们必须加入这个选项
-O:对程序进行优化编译,连接,采用这个选项,整个代码源会在编译,连接过程中进行优化处理,这样产生可执行文件的执行效率可以提高,但是,编译连接的速度就相对慢一些
-O2:比-O更好优化编译,连接,当然整个编译,连接过程会变得更慢
-l dirname:将dirname所指出的目录加入到程序文件头文件列表中,实在预处理编译过程中使用的参数/usr/include
-L dirname:将dirname所指出的目录加入到程序函数档案库文件的目录列表中,时在链接过程中使用的参数
-Wall:打开所有的语法检测错误,一般使用这个
#include<stdio.h>与#include"stdio.h"区别
" ": 用户的自定义的头文件一般使用" ",陷在当前编译目录或用户指定的目录着头文件,找不到在到系统指定的文件夹找头文件/usr/include
< >:系统文件,一般使用<>直接去系统指定的文件夹找头文件/usr/include
**指针** (以下是纯属个人对指针的理解和见解,若有错误请勿当真)
概念:地址,内部存储器的编号,称为地址。入变量int a的位置编号,变量char b的位置都是指针。
指针变量:专门存放地址的变量称为指针变量
地址。指针,指针变量都成为指针
定义变量:
1.格式[存储类型] 数据类型 指针变量名
存储类型:就是说变量放在内存的位置
数据类型:声明这个空间的大小,和地址类型
变量名:类似汇编的助记符+存放地址 相当于* 0x0xxxxxx0(表示地址)
用type来表示基本类型
例如 定义了一个type a;那么a的类型是什么呢? a的类型就是 type 和空格
在举例 type arr[10]; arr的类型为type [10];
问题来了a的地址呢 是什么类型呢
答案就是 int * 0X0xxxxxxx ;这个地址类型存储大小是几个字节呢,这要根据我们的操作系统,如果你的操作系统是32为那么他的地址存储大小是4个字节,64位就是8个字节。
定义一个地址变量
格式
1.存储类型 数据类型 *指针变量名
int i,j;
int *pointer1, *pointer2;
存储类型为这个地址变量的存储位置,数据类型的指向的即使这个地址变量指向的目标地址;
这样说可能有点晕了,我简单来说:指针的作用是什么呢? 就是用来存放地址的,地址是几个字节呢 ?这要根据你的操作系统,32为为四个字节,64位为八个字节。所以指针变量名的大小为4Byte,但是它指向的空间就是你定义这个变了的大小;我们都按照32bit操作系统来说明。
例如:
type a,*p = NULL;
p = &a;
此时指针p存放着a的地址。用sizeof(p) 他的大小永远为4Byte,因为a的地址为4个字节,所以P的大小为4Byte。但是这样做sizeof(*p),他的大小就为type 类的字节。因为使用*通过a的地址来访问a的大小,故大小就是type类型的大小。
指针的加减法:
short a = 0x100;
short *p = &a;
若a的地址为0x20008000,则
p+1 = 0x20008002;
*p+1 = 0x101
(int)p + 1 = 20008001;
(int *)p + 1 = 0x20008004;
(char *)p + 1 = 0x20008001;
(char)p + 1 = 0x1;
数组:
数组就是把相同的类型存放在一起。
例如 type a[10]; a的类型就是type [10], a类型存储空间大小就是type [10]
举例 int arr[5],a的存储大小就是四个整型的数据类型放在一起每一个int数据大小为4byte,总共为4*5=20byte此时数组名就有来过两种含义了,一种是表示整个数组,还有一个表示表示第一个元素。
为什么这要这样说呢?
因为在定义数组的时候就声明了 数组的存储大小,存储大小怎么访问呢,就是访问数组的地址,例如sizeof(arr)就是整个数组的大小。但是sizeof(arr+1)
则表示一个元素的大小,为什么回事这样呢?这是编译器的做的工作,这个sizeof(arr)情况,编译器就是认为你访问的大小就是正个空间大小,如果是arr+1,则认为是type 的类型的加一。
指针与数组
int *p,arr[10] = {0};
p = a;
把数组的第一个元素的地址赋值给p,则p就指向数组的第一个 元素,则p+1则表示这个类型的地址下一个,也就是指向下一个元素的地址。
![](http://i2.51cto.com/images/blog/201801/27/dbd3b57c0cb586ccae265483d3d16a35.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
要明白 *p++ (*p)++ *(++p) (*p++)++ ++(*++p)这几种关系的含义
二维数组和指针
同样二维数组名,有两种含义,一种是第一个元素的地址,另一个是表示整个数组。和一维数组一样,不同的是sizeof(a[0]) 表示第一行所有元素的空间大小和。这是为什么呢,因为[ ] 是变址符,本来是a的地址,给他变成第一行的首地址,用sizeof来求就是这一行的元素大小之和。
int a[3][3];
sizeof +1
a[0] 12 12
a 36 12
&a[0] 4 12
&a 4 36
以上是关于指针与数组的缘定今生的主要内容,如果未能解决你的问题,请参考以下文章