黑马程序员---c语言--指针

来源:互联网 发布:跳跳软件 编辑:程序博客网 时间:2024/05/18 12:05

指针是c语言的灵魂,也是学习中的难点,简单的理解指针其实就是地址。
一、 指针变量的定义
1. 定义的格式
类名标识符 *指针变量名;
int *p;
2. 先定义后赋值
简单取值
int a = 10;
int *p;
p = &a;
printf(“%d”, *p);
简单改值
*p = 9;
3. 定义的同时赋值
int a = 10;
int *p = &a;
4. 实现修改实参
5. 注意点
int *p; p = 1000;
int *p; *p = 100;
int *p; *p = &a;
%p输出指针里面存储的地址值
其他指针类型说明,比如float *p; char *p;
不能乱用类型,比如int a = 10; float *p = &a;
6. 清空指针
p = 0;
p = NULL;

#include <stdio.h>void change(int);int main(){    /*    int a = 90;    change(&a);    printf("a=%d\n", a);    */    // 变量类型  变量名;    // 格式:变量类型 *变量名;    // 定义了一个指针变量p    // 指针变量只能存储地址    // 指针就一个作用:能够根据一个地址值,访问对应的存储空间    // 指针变量p前面的int:指针变量p只能指向int类型的数据    int *p;    int a = 90;    // 指针变量p指向了变量a    p = &a;    *p = 10;    a = 20;    printf("%d\n", *p);    //printf("%d\n", a);    return 0;}void change(int n){    n = 10;}

使用指针时需要注意的问题,如代码演示:

#include <stdio.h>int main(){    /* 不建议的写法, int *p只能指向int类型的数据    int *p;    double d = 10.0;    p = &d;*/    /* 指针变量只能存储地址    int *p;    p = 200;    */    /* 指针变量未经过初始化,不要拿来间接访问其他存储空间    int *p;    printf("%d\n", *p);    */    int a = 10;    /*    int a;    a = 10;    */    /*    int *p;    p = &a;    */    // 定义变量时的*仅仅是一个象征,没有其他特殊含义    int *p = &a;    // 不正确的写法    // *p = &a;    p = &a;    // 这个时候的*的作用:访问指向变量p指向的存储空间    *p = 20;    char c = 'A';    char *cp = &c;    *cp = 'D';    printf("%c\n", c);    return 0;}

二、 指针与数组
1. 指向一维数组元素的指针
2. 用指针遍历一维数组元素
先遍历char数组(‘i’,’t’),再遍历int类型数组
(p+i)和(p++)的区别
a+i和a++
p[0]、p[1]

#include <stdio.h>/* 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 */void change(int array[]);int main(){    // 20个字节    int ages[5] = {10, 11, 19, 78, 67};    change(ages);    return 0;}// 利用一个指针来接收一个数组,指针变量array指向了数组的首元素void change(int *array){    printf("%d\n", array[2]);    //printf("%d\n", *(array+2));}/*void change(int array[]){    int s = sizeof(array);    printf("%d\n", s);}*/void test(){    double d = 10.8;    double *dp;    dp = &d;    printf("dp = %p\n", dp);    printf("dp + 1 = %p\n", dp + 1);    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+2));    printf("%d\n",  p[2]);    /*     for (int i = 0; i<5; i++) {     printf("ages[%d] = %d\n", i, *(p+i));     }*/    //    printf("%p\n", p);    //    printf("%p\n", p + 1);    //    printf("%p\n", p + 2);}

三、 指针与字符串
1. 字符串回顾
char s[] = “mj”;
2. 其他定义字符串的方式
char *s = “mj”;
或者
char *s;
s = “mj”;

#include <stdio.h>/* 1.常量区 存放一些常量字符串 2.堆 对象 3.栈 存放局部变量 掌握: 定义字符串的2种方式 1> 利用数组 char name[] = "itcast";  * 特点:字符串里面的字符是可以修改的  * 使用场合:字符串的内容需要经常修改 2> 利用指针  char *name = "itcast";  * 特点:字符串其实是一个常量字符串,里面的字符是不能修改  * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用 */int main(){    char name[20];    printf("请输入姓名:\n");    scanf("%s", name);    // 'j' 'a' 'c' 'k' '\0'    //printf("%c\n", name[3]);    //printf("刚才输入的字符串是:%s\n", name);    return 0;}// 定义字符串数组void test2(){    char *name = "jack";    //int ages[5];    // 指针数组(字符串数组)    char *names[5] = {"jack", "rose", "jake"};    // 二维字符数组(字符串数组)    char names2[2][10] = {"jack", "rose"};}// 定义字符串void test(){    // 字符串变量    char name[] = "it";    name[0] = 'T';    //printf("%s\n", name);    // "it" == 'i' + 't' + '\0'    // 指针变量name2指向了字符串的首字符    // 字符串常量    char *name2 = "it";    char *name3 = "it";    //*name2 = 'T';    //printf("%c\n", *name2);    printf("%p\n%p\n", name2, name3);    //printf("%s\n", name2);}

四、 返回指针的函数
指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的
返回指针的函数的一般形式为:类型名 * 函数名(参数列表)

五、 指向函数的指针
1. 为什么指针可以指向一个函数?
函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。
2. 指向函数的指针的定义
定义的一般形式:函数的返回值类型 (*指针变量名)(形参1, 形参2, …);
3. 使用注意
由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的
指向函数的指针变量主要有两个用途:
• 调用函数
• 将函数作为参数在函数间传递

#include <stdio.h>double haha(double d, char *s, int a){}/* 掌握: 1.看懂语法 2.定义指向函数的指针    double (*p)(double, char *, int);    p = haha;    或者    double (*p)(double, char *, int) = haha; 3.如何间接调用函数 1> p(10.7, "jack", 10); 2> (*p)(10.7, "jack", 10); */void test(){    printf("调用了test函数\n");}int sum(int a, int b){    return a + b;}int main(){    // 定义指针变量指向sum函数    // 左边的int:指针变量p指向的函数返回int类型的数据    // 右边的(int, int):指针变量p指向的函数有2个int类型的形参    int (*p)(int, int);    p = sum;    //int c = p(10, 11);    //int c = (*p)(10, 11);    int c = sum(10, 9);    printf("c is %d\n", c);    return 0;}void test1(){    // (*p)是固定写法,代表指针变量p将来肯定是指向函数    // 左边的void:指针变量p指向的函数没有返回值    // 右边的():指针变量p指向的函数没有形参    void (*p)();    // 指针变量p指向了test函数    p = test;    p();    //(*p)(); // 利用指针变量间接调用函数    //test(); // 直接调用函数}
0 0
原创粉丝点击