c语言指针进阶

指针变量是一种变量,指针是一个地址
错误写法:
int *a,b,c;
a是指针变量 b,c是普通变量

在被调用函数(子函数)中,不可以通过修改指针的办法来修改原来变量的值,函数调用完成以后,形式参数被释放(总之:指针变量的值无法回去,只可以修改指针变量对应地址值)

指针变量和原变量指针放在不同的内存里面
他们只是指向同一个数,交换两个数的指针变量,原变量指针不发生变化,原变量也就不会发生变化
数组名地址无法自增或自减,也不可以进行加减后取值,但是可以通过加一个数来作为判断数组结束依据

//以下代码执行效率最高:直接针对内存进行操作,不需要计算地址
for(p=a;p<a+4;p++)
printf("%d ", *p);

*(取地址)和++ --处于同一个优先级
*p++ == *(p++)//即使打了括号也是这样,先取值,再地址加一
*(++p) = *++p//先地址加一,再取值
总结:括号对自增,自减无效

(*p)++:先用 *p的值,再将’值‘加一

数组作为形参传递:
f(int a[]) == f(int *a)

实参是数组名,形参是指针变量
数组a的长度:sizeof(a) / sizeof(a[0])

二维数组:a[3][4]
**a == a[0][0]
a表示二维数组首地址,若a数组首地址为4000.则a+1地址为4016
a[0]是&a[0][0],a[1]是&a[1][0]
a[0][2] = a[0] + 2 //a[0]地址为4000 a[0] + 2地址为4008
第一行元素首地址:a[0] == *a == *(a+0)
第i行的第2个元素的地址为 *(a+i-1)+1
a[0]+2 == &a[0][2]
第二行第三个元素的地址为:&a[1][2] == a[1] + 2 == *(a+1) + 2
*(a+1)//表示a[][] (&&a) *抵消掉一个& 私人理解不知道对不对方便记
第一行首地址,第一行第一列地址:
*a == &a[0][0] == *(a+0)+0 == a[0]
第二行首地址:
*(a+1) == a[1] == &a[1][0]

打印第二行第三个元素:
printf("%d %d %d", a[1][2],(a[1]+2),(*(a+1)+2));

第二行的首地址:a[1] == a+1

int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int i,n,(*p)[4];//必须将二维数组的列数定义出来
//(*p)[4] 不能写成 *p[4]因为[ ]优先级高于 * 会被认为是指针数组
n = sizeof(a) / sizeof(**a);
p = a;// p 不能写成 int **p
for(p=a;p<a+3;*p++)
for(i=0;i<4;i++)
printf("%d ", (*p)[i%4]);

一维数组地址加上数字为二维数组的地址

char *str = “hello” == char str[] = "hello"都会在结尾自动加上‘\0’
*str都表示数组的首地址的值
也可以写成char *str
str = “hello”
除了自己手动输入的数组需要在数组末尾手动输入‘\0’以外,其他以函数方式输入的形式都会自动在数组末尾输入’\0’

for(;st[i];i++)//前提int i=0
printf("%c",st[i]);
//会自动从数组的首地址开始判断 等价于 for(i=0;st[i];i++)

char *str;
gets(str);//错误,不能使用gets给直接给指针赋值,可以char str[ ]
需要加上在赋值前面加上动态内存分配malloc

char * a = “hello” //是宏定义,之后无法改变其值,访问速度比数组快,但是没有给a分配内存单元,最保险方式是初始化时就赋值 char a[] = “hello”//以后可以改变其中数的值,若将数组名当做参数传递给子函数,子函数中可以使用指针形式 a++,但在定义数组的函数中不行
sizeof(char
) == 4
sizeof(*a) == 1
指针数组在地址自增时会自动给自己分配内存
a++之后 a的地址不再是首地址而将永远变成首地址的下一位地址,所以可以提前将其首地址保存下来

指针数组:
char *str[] = {“Good moring”,“C Program Language”,“Data Struture”,“Microsoft Corporation”};
指针所存一维数组个数为sizeof(str) / sizeof(str[0]);即使每个一维数组长度不同计算出任然是正确答案
这样可以判断指针数组的结束

指向指针的指针也称为二级指针,定义方法:char **p
char *str[] = {“Microsoft Corporation”,“Good moring”,“Data Struture”,“C Program Language”};
char **p = str + 2;
printf("%s", *p);输出:"Data Struture

float a[4] = {1.1,2.1,3.1,4.1};
float *b[4] = {&a[0],&a[1],&a[2],&a[3]};
float **p = b;
int i=0;
while(i<4)
{
	printf("%3.1f  ", **p+i);        // **p+i  !=    *(*p+i)  

// **p+i 表示当前地址值加i
	i++;
}

调试方法:项目->Text属性
argc:参数个数(a), argv[]:参数(argv[0] …………argv[a-1])
void main(int argc ,int *argv[])
{
int i;
for(i=0;i<argc;i++)
printf("\n%s", *argv++);
}

指向函数的指针:
float average(float x, float y);
int main()
{
float a, b, aver;
float (*p)(float,float);
scanf("%f %f",&a, &b);
p = average;
aver = p(a,b); == (*p)(a,b) == average(a,b)
printf("%f",aver);
}
float average(float x, float y)
{
float z;
z = (x+y)/2;
return z;
}
对于函数指针不可以进行p++, p–

将函数指针作为函数参数然后用指针形式调用函数,主要用在调用函数不确定的情况:
float subtract(float x, float y);
float add(float x, float y);
float average(float a,float b,float (*p)(float,float));

int main()
{
float a, b, aver;
scanf("%f %f",&a, &b);
aver = average(a,b,add);
printf("%f\n", aver);
aver = average(a,b,subtract);
printf("%f", aver);
}
float average(float a,float b,float (*p)(float,float))
{
float z;
z = p(a,b);
return z;
}
float add(float x, float y)
{
float z;
z = (x+y);
return z;
}
float subtract(float x, float y)
{
float z;
z = (x-y);
return z;
}

返回指针的函数:
int *search(int (*ptr)[4], int n);
void disp(int *ptr);

int *search(int (*ptr)[4], int n);

int main()
{
int a[3][4] = {{92,76,88,83},{78,93,73,65},{95,88,63,72}};
int n,*m;
scanf("%d",&n);
m = search(a,n-1);
disp(m);
return 0;
}
int *search(int (*ptr)[4], int n)
{
int *p;
p = (ptr+n); == return ((ptr + n));
// &&a[0][0] + n = &&a[n][0];
//&a[0][0] + n = &a[0][n];
return p;
}
void disp(int *ptr)
{
int i;
for(i=0;i<4;i++)
printf("%d ",*ptr++);
}
输入:2
输出:78 93 73 65

int a[2][2];
(&a+1) 表示数组的末地址;
a表示指向a[0] (元素首地址)
&a表示指向a[0][0]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

world呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值