您的位置:首页 > 编程语言 > C语言/C++

黑马程序员 C语言 - 07 指针

2014-08-29 19:51 148 查看
若排版错误,请查看PDF:C语言 - 07 指针.pdf

第十四章 指针

一、  指针的定义

1.     格式

变量类型 *变量名

int *p;

1)     定义了一个指针变量p,*仅仅是一个象征,没有其他特殊含义

2)     指针变量p前面的int:指针变量p只能指向int类型的数据

3)     指针变量只能存储地址

4)     任何指针都占用8个字节

char *ap;
int *bp;
long *cp;

5)     指针就一个作用:能够根据一个地址值,访问对应的存储空间

 

2.     简单使用

1)     赋值

int a =
90;
int p;
// 定义了一个指针变量p,
*仅仅是一个象征,没有其他特殊含义
p = &a; // 指针变量p存入变量a的地址,指向了变量a
// int *p = &a;
*p =10; // *的作用:访问p指向的地址空间(变量a),a值变为10

 

2)     修改变量的值

void change(int *n);
4000

  int main()
  {
     int a =
90;
     change(&a);
     printf("%d\n", a);
// 10
     return
0;
  }
  void change(int *n)
  {
     *n = 10;
 }

 
3)     交换变量的值

#include <stdio.h>
void swap(int *v1,int *v2);
void swap2(int *v1,int *v2);
void swap3(int v1,int v2);
 
int main()
{
    int a =
90;
    int b =
89;
    swap(&a, &b);
    printf("a=%d,b=%d\n", a, b);// a、b的值交换
   
    swap2(&a, &b);
 
    swap3(a, b);
    return
0;
   
}
 
// 完成两个整型变量值的互换
void swap(int *v1,int *v2)
{
    int temp = *v1;
    *v1 = *v2;
    *v2 = temp;
}
 
// 不能交换外面实参的值,仅仅是交换了内部指针的指向
void swap2(int *v1,int *v2)
{
    int *temp;
    temp = v1;
    v1 = v2;
    v2 = temp;
}
 
//交换的只是内部v1、v2的值
void swap3(int v1,int v2)
{
    int temp = v1;
    v1 =v2;
    v2 = temp;
}

 

3.     注意

1)     不建议的写法,int *p只能指向int类型的数据

int *p;

    double d =
10.0;
       p = &d;
 

2)     指针变量只能存储地址

int *p;

p = 200;

 

3)     定义变量时的*仅仅是一个象征,没有其他特殊含义

int *p = &a;

 

4)     *p = 20;

这个时候的*的作用:访问指向变量p指向的存储空间

不正确的写法

*p =&a;

 

5)     指针变量未经过初始化,不要拿来间接访问其他存储空间

int *p;

printf("%d\n", *p);

 

6)     清空指针(清空指针后不能再间接访问存储空间)

p = 0;
p = NULL;

 

二、  指针与数组

    #include <stdio.h>
    void change(int array[]);
    int main()
    {
        // 20个字节
        int ages[5] = {10,9,
8, 67,
56};
       
        int *p;
        // 指针变量p指向了数组的首元素
        p = &ages[0];
        // 数组名就是数组的地址,也是数组首元素的地址
        // p = ages;
       
        // 访问数组元素
        /*
         p ---> &ages[0]
         p + 1 --->&ages[1]
         p + 2 --->&ages[2]
         p + i --->&ages[i]
         */
        printf("%d\n", *(p+1));//printf("%d\n", p[1]);
        // 指针变量+1,地址值究竟加多少,取决于指针的类型
   
        for (int i =0; i<5; i++) {
            printf("ages[%d] =%d\n", i,*(p+i));
        }
   
        change(ages);
// 将数组当做函数参数传入时,会自动转为指针
      
        return
0;
    }
 
    // 利用一个指针来接收一个数组,指针变量array指向了数组的首元素
    void change(int *array)
    {
        printf("%d\n", array[2]);// 8
        //printf("%d\n",*(array+2));
    }
 

1.     数组元素的访问方式

    int ages[5];
    int *p;
    p = ages;
1)     数组名[下标] ages[i]

2)     指针变量名[下标] p[i]

3)     *(p + i)

 

2.     指针变量+1,地址值究竟加多少,取决于指针的类型

    int *     
4
    char *    
1
    double *  
8
 

三、  指针与字符串

1.     内存

1)     常量区

存放一些常量字符串

2)     堆

存放对象

3)     栈

存放局部变量

 

2.     定义字符串

1)     利用数组

特点:字符串变量,里面的字符可以修改
使用场合:字符串里的内容需要经常修改
char name1[] =
"it"; // "it" == 'i' + 't' + '\0'
printf("%s\n", name1);// it

 

char name2[20];

printf("请输入姓名:\n");

scanf("%s", name2);//
如:jack内存中为:'j''a' 'c' 'k' '\0'

printf("%c\n", name2[3]);// k

printf("刚才输入的字符串是:%s\n", name2);// jack

 

2)     利用指针

特点:字符串常量,里面的字符不能修改
使用场合:字符串的内容不需要修改,而且这个字符串经常使用
char *name3 =
"it"; // 指针变量name2指向了字符串的首字符printf("%c\n",
*name3); // i
printf("%s\n", name3);// it
 

3.     定义字符串数组

1)     指针数组(字符串数组)

char *name =
"jack";
 
//int ages[5];
      // 指针数组(字符串数组)
char *names[5] = {"jack","rose",
"jake"};

 

2)     二维字符数组

char names2[2][10] = {"jack","rose"};

 

四、  返回指针的函数

指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的

类型名 *函数名(参数列表)

 

    char *test()
    {
       return
"rose";
    }
 

    int main()
    {
        char *name = test();
        printf("name=%s\n", name);
        return
0;
    }
 

五、  指向函数的指针

1.     为什么指针可以指向一个函数

函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。利用一个指针存储函数的地址就可以指向函数。其中,函数名就代表着函数的地址。

 

2.     指向函数的指针的定义

函数的返回值类型 (*指针变量名)(形参列表)

 

    void (*p)();
1)     (*p)是固定写法,代表指针变量p将来肯定是指向函数

2)     左边的void:指针变量p指向的函数没有返回值

3)     右边的():指针变量p指向的函数没有形参

 

p = test;
// 指针变量p指向了test函数
 

3.     利用指针变量间接调用函数

1)     指针变量名(形参列表)

2)     (*指针变量名)(形参列表)

 

//利用指针变量间接调用函数
    p();
(*p)();
    // 直接调用函数
test();

 

    int (*p)(int,int);
    p = sum;
    // 定义指针变量指向sum函数
    // 左边的int:指针变量p指向的函数返回int类型的数据
    // 右边的(int, int):指针变量p指向的函数有2个int类型的形参
   
    // 利用指针变量间接调用函数
    int c = p(10,11);
    int c = (*p)(10,11);
   
    // 直接调用函数
int c = sum(10,9);

 

4.     使用注意

1)     由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的

2)     指向函数的指针变量主要有两个用途:

a)      调用函数

b)     将函数作为参数在函数间传递

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息