字符指针变量
int main()
{
//char ch='h';
//*p=&ch;
//*p='a';
char ch="abcded"; //这里的赋值是将字符串中首字符的地址赋值给p
char* p=&ch
return 0;
}
这里的“abcdef”是常量字符串,常量字符串不能被修改
int main()
{
const char* pa = "hello,everybody";
printf("%s\n", pa); //注意这里不用加*---pa
return 0;
}
只是⼀个常量字符串的⾸字符 h 的地址存放到指针变量 pstr 中,
并不是将一整个”hello,everybody“放到pa里面去
在指针中,内容相同的常量字符串,只需保存一份就可以了
eg:其实都一样,存放在同一个地址(因为常量字符串不可修改)
比的是存的地址
const char *p1="hello";
const char *p2="hello";
但是,下面两个不等同
这个不一样:比的是他们所在首个元素的地址
char str1[] = "hello bit.";
char str2[] = "hello bit."
总结:
⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。
但是⽤相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
数组指针变量
回顾:
指针数组---是数组,存放的是指针(地址)
整形指针变量:存放的是整形变量的地址,能够指向整形数据的指针。
所以,数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。
区分:
int arr[10]={0};
//指针数组
int* p[10]=&arr;
//数组指针
int (*p)[10]=&arr;
数组指针:
p就是数组指针,p存放的是数字的地址
类型:去掉名字 int(*)[10]
各种arr的类型:
arr ---int* arr+1跳过4个字节
&arr[0]--int* &arr[0]+1跳过4个字节
&arr--int(*)[10] &arr+1跳过40个字节
使用时容易出错的地方:
因为 []的优先级要⾼于*号的,所以必须加上()来保证p先和*结合
数组指针变量怎么初始化
数组指针变量是⽤来存放数组地址的----&arr就得到了数组的地址了
如果要存放数组的地址,就得存放在数组指针变量中
int (*p)[10]=&arr;
这个p是指向数组的,本来拿到的是数组的地址,
如果解引用*,拿到了那个数组,相当于拿到了数组名arr,而数组的元素是由下标访问的,所以加个[i],也就是上面的10
int a=20;
int* p=&a; //---拿到a的地址,把它交给p,再解引用*p,找回a
*p //这相当于*&a,即*&a=a
int (*p) [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是数组指针变量名, 这个p放的是数组的地址,当进行解引用*时,相当于拿到了整个数组,
| 所以当取出数组的每个元素,仍然是从下标出发的
| eg:printf("%d",(*p)[i])
p指向的数组的元素类型
⼆维数组传参的本质
回顾:
一维数组传参
数组名就是首位元素的地址
一维数组在传参的时候,其实传递的是首位元素的地址
函数的参数可以写成数组,也可以写成指针
二维数组?
二维数组的数组名是如何理解的呢?
其实二维数组的数组名也是数组首位元素的地址
二维数组可以理解为一维数组的数组
二维数组的数组名就是他第一行得到地址
第一行是一个一维数组
传过去就是第一行这个一维数组的地址
数组的地址存在哪里?指针那里
int(*arr)[5]
二维数组的解读:
假设有
int arr[i][j]={0}一些二维数组
⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式
函数指针变量
1.创建:与arr数组非常相似
arr==&arr
我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针⾮常类似。
这意思是加不加&,存放起来的地址都是一样的
注意:
函数指针中时,
eg:(*p)(int ,int ),前面的一定要有括号,否则它p会与后面的先结合,而不先与*结合
int (*pf3) (int x, int y)
| | ------------
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
去掉函数指针变量名后就是函数指针的类型了
各种函数区别:
1.函数定义:
int Add(int x,int y)
{
return x+y;
}
2.函数调用:
Add(3,5);
3.函数声明:
int Add(int,int);
typedef 关键字
1.用来类型重命名的
2.意思就是后续如果再用到unsigned int这个关键词,你就可以写成uint就可以了。
这大大提高了写的速度
typedef unsigned int uint
int main()
{
unsigned int p1;
uint p2=20;
printf("%d",p2);
return 0;
}
但是,对于数组指针和函数指针稍微有点区别
typedef int (* parr)[5]; //新的类型名必须在*的右边
int main()
{
int (*p)[5]={1,2,3,4,5};
parr [5] =;
printf("%d",parr[5]);
return 0;
}
函数指针类型的重命名也是⼀样的,
⽐如,将 void(*)(int) 类型重命名
typedef void(*pfun_t)(int); 新的类型名必须在*的右边
函数指针数组
int (*parr1[3])();