指针和数组

来源:互联网 发布:linux查看hba卡状态 编辑:程序博客网 时间:2024/05/16 10:11

指针和数组参在一块确实很让人头疼,特别是对于我这种菜鸟级别的,简直一个晕字了得。
可是再难也得学啊,那就慢慢捋捋吧。。。。。。
一、指针
1. 在计算机内存中,每一个内存单元都有一个地址,在c语言中这个地址就大概可以充当指针。
2. &和*
&是对变量取地址,*是对取变量的值。互为逆运算。
3. 地址的打印;

#include <stdio.h>int main(void){   int a = 3;   int *p = &a;printf("%p\n",&a);//打印a的地址需用p%printf("%p\n",p);//此时p = &a,即为打印a的地址需用p%printf("%p\n",&p);//p本身是指针变量,即为一个地址,&p是对p取地址,也就是对a的地址再取地址printf("%d\n",*p);//打印a的值;return 0;} //运行结果: //0xbfe758b8//0xbfe758b8//0xbfe758bc//3
  1. 指针大小
#include <stdio.h>int main(void){    char *p = "hello world";//指针p中只存放了字符串的首地址;    int *q = NULL//初始化指针q;    double *p1 = NULL//32位操作系统,指针变量的大小恒为4个字节,不论数据类型是什么;    printf("%d,%d,%d\n",sizeof(p),sizeof(q),sizeof(p1));    return 0;}//运行结果://4,4,4
  1. 二级指针
    只有变量才有地址,常量放在寄存器中,没有地址;
    二级指针:地址的地址,常量没有地址。
    一级指针和二级指针的比较:
#include<stdio.h>int fun(char *str){    str = "helloworld"; return 0;}int main(int argc, const char *argv[]){ char *str = NULL; printf("%p\n",str); fun(str); printf("%p\n",str); puts(str); return 0;}==========================================#include<stdio.h>int fun(char **str){     *str = "helloworld"; return 0;}int main(int argc, const char *argv[]){     char *str = NULL;     printf("%p\n",str);     fun(&str);     printf("%p\n",str);     puts(str); return 0;}

二、数组
1. 例如:int a[5] = {1,2,3,4,5};
char b[6] = “hello”;
其中数组名代表数组的首地址,也就是表示这个数组的开始地址。
当数组为字符串的时候,数组最后一位有’\0’结束符。
2. 指针与数组

#include <stdio.h>int main(void){    int a[5] = {1,2,3,4,5};    int *p = a;    printf("%d,%d,%d,%d\n",a[1],*(p+1),*(a+1),p[1]);    //此时,a[1] = *(p+1) = *(a+1) = p[1];    return 0;}//结果://2222
  1. 二维数组
    二维数组:a(行地址指针) —->*a(降级变为列指针)—->**a(再降级变为 元素)
    **a—>&(**a)(*a升级为列地址)—–>&*a(a 升级为行地址)
#include <stdio.h>int main(){ char ch[3][3] = {1,2,3,4,5,6,7,8,9}; int i,j; for (i = 0; i < 3; i ++) {  for (j = 0; j < 3; j ++)   printf("%12d",ch[i][j]);  putchar(10); } for (i = 0; i < 3; i ++) {  for (j = 0; j < 3; j ++)   printf("%12p",&ch[i][j]);  putchar(10); }#if 1/* 二维数组中ch代表行地址,ch[0]代表列地址;ch[0][0]代表是元素   */ printf("&ch + 1 = %#x\n",&ch + 1); // char(*)[3][3];        //   ch代表行地址,取&升级为数组,数组+1,指向整个数组下一个地址 &ch代表整个数组的首地址,而ch代表数组首元素的地址,虽然两者值相等,但意义不一样。 printf("&ch[1][0] = %#x\n",&ch[1][0]);                          //   取ch[1][0]的地址        printf("ch + 1 = %#x\n",ch + 1);                                      //   ch代表行地址,+1,表示行地址加1,换一行; printf("ch[0] = %#x\n",ch[0]);                                         //   ch[0]代表是ch[0][0]的地址        printf("ch[0] + 1= %#x\n",ch[0] + 1);                              //   ch[0]是列地址,+1,表示列地址加1;ch[0][1]的地址  printf("ch[1] + 3 = %#x\n",ch[1] + 3);                            //    ch[1]是列地址;+3,表示列地址加3;ch[1][3];即为ch[2][0]的地址 printf("*(ch[0] + 2) = %#x\n",*(ch[0] + 2));                    //    ch[0]是列地址;+2,代表列地址+2;ch[0][2]的地址; printf("*ch[1] = %#x\n",*ch[1]);                                    //    ch[1]是列地址;*ch[1],降级为元素;ch[1][0]的元素 printf("&ch[1] + 1 = %#x\n",&ch[1] + 1);// ch + 1 + 1    //    ch[1]是列地址;&ch[1],升级为行地址;&ch[1]+1;行地址加1;ch[2][0] 地                                                                                              址                                                                                                                                                                                                                                    printf("*(*(ch + 1) + 1) = %#x\n",*(*(ch + 1) + 1));        //    (ch+1)行地址加1;*(ch+1),降级为列地址ch[1];(*(ch+1)+1),为ch[1][1]地址; printf("*(*(&ch[0] + 1) + 1) + 1 = %#x\n", *(*(&ch[0] + 1) + 1) + 1 );            // printf("ret = %#x\n",*(*(ch + 1) + 2) + *(*(&ch[1] + 1)) + 1 );                          //#endif return 0;}    

运行结果:
这里写图片描述

三、指针数组、数组指针
指针数组为一个数组,
char *p[3] = {“hello”,”world”,”hi”};
p[0] = “hello”的地址, p[1] = “world”的地址, p[2] = “hi”的地址。
当用“%s”打印p[0]这个地址指向的值,即为“hello”;当用“%p”打印时,则是打印p[0]的地址。
数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。

如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]…p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。

这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。

四、函数指针,指针函数
函数指针:实质上是一个指针,指向一个函数。
指针函数:实质上是一个函数,返回值是一个指针。

1 0
原创粉丝点击