C语言指针进阶介绍

1、字符指针

const char* p = "abcdefg";//"abcdefg"是一个常量字符串。把首元素a的地址赋给p

//常量字符串不允许被改变,可以加const修饰

//容易以为是把字符串abcdefg放到字符指针p里了,但本质是把字符串abcdefg首字符的地址放到p中。

printf("%c\n", *p); //a

printf("%s\n", p);   //abcdefg

下面代码存在问题

//*p = 'W';//常量字符串不能被改变,代码会崩溃

//printf("%s\n", p);

面试题,输出结果是什么?

char str1[] = "hello bit.";

char str2[] = "hello bit.";

const char* str3 = "hello bit.";

const char* str4 = "hello bit.";//常量字符串,理论上不能被修改,只能拿去用。加const修饰。

str3str4的内容一样,常量字符串为了节省内存空间,存一份就可以了。str3str4都指向同一块空间的起始位置。

数组名是首元素地址,首元素地址在不同的空间,所以str1 = str2

if (str1 == str2)

{

        printf("str1 and str2 are same\n");

}

else

{

        printf("str1 and str2 are not same\n");

}

//str3和str4都指向同一块空间的起始位置。

if (str3 == str4)

{

        printf("str3 and str4 are same\n");

}

else

{

        printf("str3 and str4 are not same\n");

}

分析:这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。数组其实是放在内存的栈上,常量字符串是放在内存的只读数据区。所以str1和str2不同,str3和str4不同。

2、指针数组

指针数组是数组,用来存放指针的数组。

int arr[10] = { 0 };  //整型数组

char ch[5] = { 0 };  //字符数组

int* parr[4];          //存放整形指针的数组 - 指针数组

char* pch[4];       //存放字符指针的数组 - 指针数组

char **arr3[5];     //二级字符指针的数组

例:

int a = 10;

int b = 20;

int c = 30;

int d = 40;

int* pa[4] = { &a,&b,&c,&d };

int sz = sizeof(pa) / sizeof(pa[0]);

//printf("sz = %d\n", sz);

int i = 0;

for (i = 0; i < sz; i++)

{

       printf("%p\n", pa[i]);     //指针数组存放的是整形指针,打印的是地址

}

for (i = 0; i < sz; i++)

{

       printf("%d ", *(pa[i]));//整形指针解引用,拿到地址中的内容

}

例:

数组名是首元素地址

int arr1[] = { 1,2,3,4,5 };//整型数组

int arr2[] = { 2,3,4,5,6 };//整型数组

int arr3[] = { 3,4,5,6,7 };//整型数组

//通过存放在指针数组中的数组名,打印数组中的元素

int* parr[] = { arr1,arr2,arr3 };//存放整形指针的指针数组,里面的数组名是首元素地址。

int i = 0;

for (i = 0; i < 3; i++)

{

       int j = 0;

       for (j = 0; j < 5; j++)

       {

              printf("%d ", *(parr[i] + j));

              //指针 +- 整数。指针的类型决定了指针向前或者向后走一步有多大(距离)。

}

       printf("\n");

}

3、数组指针

数组指针是指针还是数组?答案是指针。

int* pint = NULL;  //整形指针:能够指向整型的指针,可以存放整型的地址。

char* pc = NULL;  //字符指针:指向字符的指针,可以存放字符的地址。

float* pf = NULL;  //浮点型指针:能够指向浮点型数据的指针,可以存放浮点型的地址。

数组指针应该是:能够指向数组的指针,可以存放数组的地址。

写法等价,arr[i] == *(p + i) == *(arr + i) == p[i]

int(*p)[10] = &arr;

//*首先与p结合,p就是数组指针。*表示p是指针,[ ]表示指针指向的是数组,每个元素是int类型

//数组指针是能够指向数组的指针,可以存放数组的地址。

那数组指针是怎么使用的呢?

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

数组指针至少用在二维数组以上才方便一些。

4、函数指针

数组指针 - 是指向数组的指针 - 存放数组的地址

函数指针 - 是指向函数的指针 - 存放函数地址的指针

&函数名和函数名都是函数的地址

int Add(int x, int y)

{

       int z = 0;

       z = x + y;

       return z;

}

void Print(char* str)

{

       printf("%s\n", str);

}

int main()

{

       //数组指针 - 是指向数组的指针 - 存放数组的地址

       //函数指针 - 是指向函数的指针 - 存放函数地址的指针

       //int a = 10;

       //int b = 20;

       //printf("%d\n", Add(a, b));

       //&函数名和函数名都是函数的地址

       //printf("%p\n", &Add);//打印的是Add函数的地址

       //printf("%p\n", Add);//打印的是Add函数的地址

       int (*pa)(int, int) = Add;

       printf("%d\n", (*pa)(2, 3));

       printf("%d\n", Add(2, 3));//函数名是函数的地址

       printf("%d\n", pa(2, 3));//pa是函数指针,存放的是函数地址,函数名也是函数的地址,所以调用函数的时候可以不解引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挨踢牛马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值