C语言进阶要点笔记2


目录

  • 四、指针

7、字符串和指针
8、数组指针
9、数组名字取地址
10、指针变量和数组名的区别
11、多维数组中指针的转换
12、指针做函数的参数


  • 四、指针

7、字符串和指针

a、 char string[100] = “I love C!”
              定义了一个字符数组 string,用来存放多个字符, 并且用”I love C!”给 string 数组初始化
              字符串“I love C! ” 存放在 string 中
       b、 char *str = “I love C!”
              定义了一个指针变量 str,只能存放字符地址编号,
              所以说 I love C! 这个字符串中的字符不能存放在 str 指针变量中。
              str 只是存放了字符 I 的地址编号, “I love C! ” 存放在文字常量区
       c、 char *str =(char*)malloc(10*sizeof(char));//动态申请了 10 个字节的存储空间,首地址给 str 赋值。
              strcpy(str, "I love C"); //将字符串“I love C!” 拷贝到 str 指向的内存里


               字符数组:在内存(栈、 静态全局区) 中开辟了一段空间存放字符串

                             可修改,可直接初始化
               字符串指针:在文字常量区开辟了一段空间存放字符串, 将字符串的首地址付给 str

                                 不可修改,可直接初始化
               堆:使用 malloc 函数在堆区申请空间, 将字符串拷贝到堆区
                         可修改,不能直接初始化

指针指向的内存是否能修改取决于指针指向的位置,指向文字常量区不可修改,指向栈、堆、静态全局区可修改

字符数组: 使用 scanf 或者 strcpy

buf_aver="hello kitty"; //错误,因为字符数组的名字是个常量
strcpy(buf_aver,"hello kitty"); //正确
scanf("%s",buf_aver); //正确

指向字符串的指针:

buf_point="hello kitty"; //正确,buf_point 指向另一个字符串
strcpy(buf_point,"hello kitty"); //错误,只读,能不能复制字符串到 buf_piont 指向的内存里取决于 buf_point 指向哪里。

8、数组指针(是指针)

概念:本身是个指针,指向一个数组,加一跳一个数组,即指向下一个数组

定义方法:指向的数组的类型 (*指针变量名) [指向的数组的元素的个数]

                 int (*p)[5];//定义了一个数组指针变量 p, p 指向的是整型的有 5 个元素的数组,即每一个小数组都有五个整形变量
                        p+1 往下指 5 个整型, 跳过一个有 5 个整型元素的数组。

区别   数组指针:int (*p) [5]  是指针,只有四个字节

                            int  *p[5]   是数组,有五个整形指针

#include <stdio.h>
int main()
{
int a[3][5];//定义了一个 3 行 5 列的一个二维数组
int(*p)[5];//定义一个数组指针变量 p, p+1 跳一个有 5 个元素的整型数组
printf("a=%p\n",a);//第 0 行的行地址
printf("a+1=%p\n",a+1);//第 1 行的行地址, a 和 a +1 差 20 个字节
p=a;
printf("p=%p\n",p);
printf("p+1=%p\n",p+1);//p+1 跳一个有 5 个整型元素的一维数组
return 0;
}

$ 一维数组指针int(*p)[5] ;  配合每行有 5 个 int 型元素的二维数组来用

$ 二维数组指针int(*p)[4][5];  配合三维数组来用, 三维数组中由若干个 4 行 5 列二维数组构成

$ ...

容易混淆的内容:
                                 指针数组: 是个数组, 有若干个相同类型的指针构成的集合
                                                    int *p[10];
                                                    数组 p 有 10 个 int *类型的指针变量构成, 分别是 p[0] ~p[9]
                                 数组指针: 本身是个指针, 指向一个数组, 加 1 跳一个数组
                                                    int (*p)[10];
                                                    P 是个指针, p 是个数组指针, p 加 1 指向下个数组, 跳 10 个整形。
                                 指针的指针:
                                                    int **p;//p 是指针的指针,可以保存int *类型的地址
                                                    int *q;
                                                    p=&q;
9、数组名字取地址

指针:变量取地址

指针的指针:指针变量取地址

数组指针:数组名字取地址

                  int a[10];
                         a+1 跳一个整型元素, 是 a[1]的地址
                         a 和 a+1 相差一个元素, 4 个字节
                         &a 就变成了一个一维数组指针,是 int(*p)[10]类型的。
                         (&a) +1 和&a 相差一个数组即 10 个元素即 40 个字节。

c 语言规定, 数组名字取地址, 变成了数组指针。 加 1 跳一个数组

10、指针变量和数组名的区别

int a[10];

int *p;

p = a;

相同点:a和p指向相同的地址,在数组元素引用时等价

不同点:a是常量,p是变量;p可以赋值,a不能赋值

              对a取地址是数组指针,对p取地址是指针的指针

11、多维数组中指针的转换

在二维数组中, 行地址 取 * 不是取值得意思, 而是指针降级的意思, 由行地址(数组指针) 变成这一行第 0
个元素的地址。 取*前后还是指向同一个地方, 但是指针的类型不一样了

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[3][5];
    printf("a=%p\n",a);
    printf("a +1=%p\n",a+1);
    printf("*a =%p\n",*a);// *a 变成了第 0 行第 0 列元素的地址
    printf("(*a)+1 =%p\n",(*a)+1 ); //结果为第 0 行第 1 列元素的地址
    return 0;
}

12、指针做函数的参数

调用函数的时候传变量的地址,在被调函数中通过*+地址俩改变驻点函数中变量的值

要想改变主调函数中变量的值,必须传入变量的地址,而且还得通过 *+地址 去赋值,无论这个变量是何类型

void fun(char **q)
{
    *q="hello kitty";
} 

int main()
{
    char *p="hello world";
    fun(&p);
    printf("%s\n",p);//结果为: hello kitty
}

给函数传数组的时候不能将数组一次性全部传进去,只能传数组的地址

传一维数组时:void fun(int p[])  或者   void fun(int *p)                     //二者等价,都是指针

传二维数组时:void fun(int p[][4])   或者   void fun(int (*p)[4])

传指针数组时:

void fun(char **q) // char *q[]
{
    int i;
    for(i=0;i<3;i++)
    printf("%s\n",q[i]);
} 

int main()
{
    char *p[3]={"hello","world","kitty"}; //p[0] p[1] p[2] char *
    fun(p);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值