黑马程序员——指针、指针与数组、指针与字符串

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


指针:

举例说明指针和基本类型的区别

基本数据类型作为函数参数纯粹是值的传递。例如:

#include <stdio.h>
void change(int);
int main()
{
int a = 90;
change(a);
printf("%d\n", a);
return 0;
}
void change(int n)
{
n = 10;
}   

    输出结果为90.调用函数时将90传递给n,n=90,然后n被修改成10,但a的值不变。要想在函数里修改a的值必须用指针,即传递a的地址,通过地址修改a的值。

    定义指针:int *p; //指针变量只能存储地址。能根据一个地址值,访问对应的存储空间。

int main()
{
int a = 90;
int *p;
p = &a; // 把a的地址给p
*p = 10; // 将p地址下的值赋值为10.
printf("%d\n", a);
return 0;
}  // 输出10

指针的练习:

<span style="font-size:18px;">#include <stdio.h>
void change(int *n);
int main()
{
int a = 90;
change(&a); // 传递地址
printf("%d\n", a);
return 0;
}
void change(int *n)
{
*n = 10;
}       // 输出结果为10
</span>

指针的使用注意:

1、指针变量只能指向地址。

2、指针分类型,如int类型的指针只能指向int型。

     int *p; printf(“%d”, *p);  这是不合理的写法,指针未初始化,不要拿来间接访问其他存储空间。

     int *p = &a;  定义指针的时候指针变量前的* 号就是一个标志,这句就相当于 int *p;p = &a; 也可以理解为 (int *)p=&a;但不能写为 *p = &a; 定义指针时的*号 和用指针时的*号 含义不一样。这时候*p代表p地址指向的内容。

指针练习:

编写一个函数,输出两个整数的和、差。

<span style="font-size:18px;">#include <stdio.h>
int sumandminus(int n1, int n2, int *n3);
int main()
{
int a = 10; int b = 7;
int he; int cha; 
he = sumandminus(a, b, &cha);  // 传递地址
printf("和是%d, 差是%d\n", he, cha);
return 0;
}

</span>
<span style="font-size:18px;">int sumandminus(int n1, int n2, int *n3)
{
   *n3 = n1 – n2; // 只要知道地址就能修改值
   return n1 + n2;
}</span>


关于指针内存的研究疑惑:

        任何类型的指针都占用8个字节(64位编译器中),用sizeof() 求的长度输出的是unsigned long型,用%zd 表示 。

        那么为什么要分类型呢?

        如果定义一个char c = 1;int*p; p = &c; printf(“%d\n”, *p); 则输出不正确。因为一个整数类型指针*p默认占4个字节,你取值的时候它会从它指向的那个字节向下取四个字节,即取到上图的ffc8。定义指针类型是为了取值和赋值的时候能正确。

指针与数组:

int ages[3] = {10,12,14};int *p; p = ages; 

和p = &ages[0];是一样的,因为数组的名称就是数组的地址,也是数组首元素的地址。p + 1就是ages[1]的地址。即要取出ages[1]的值,可写为 printf(“%d\n”, *(p + 1));也可以写为printf(“%d\n”, p[1]);  数组跟指针很密切,在这里相当于数组。

指针变量的+1究竟加多少字节,取决于指针的类型(和内存有关),指向下一个元素,例如上面的p+1  在内存中加了4个字节。

<span style="font-size:18px;">#include <stdio.h>
void change(int *array);
int main()
{
int ages[5] = {10,8,32,26,87};
change(ages); // 将数组的首元素地址传给指针*array。
return 0;

}
void change(int *array)  // 定义一个函数  参数为指针变量
{
printf("%d\n", *(array + 1));
}  //  输出值为8</span><span style="font-size:14px;">
</span>

指针与字符串:

内存分几大块:

1、常量区  存放一些常量

2 、堆  对象

3 、栈  存放局部变量 例如常定义的整形a,数组name[ ]的

 

char name[ ] = “it”; // 定义字符串变量,里面的字符可以改 。例,name[0]= ‘y’;适用于字符串内容常修改

char *name = “it”; // 指针变量name指向了字符串的首字符i,这个用法最常见。定义的是一个字符串常量,里面的字符不可以改。适用于字符串内容不需修改,且经常用到。

printf(“%c\n”, *name);  // 输出name的首字符i。

printf(“%s\n”, name);  // 输出整个字符,因为%s只有遇见’\0’ 才会停止。

 (如果再这个函数中定义一个char *name1 = “it”; 这和char *name = “it”访问的是同一个内存同一个东西。)

 

指针数组和字符串:

char *names[3] = {“jack”, “rose”, “jim”};和以前的字符串数组比较,char names[2][10] = {“jack”, “rose”};(表示两行字符串,一行最长为十个字符);

以上是保存字符串数组的两种表示方式

 

字符串的输入:用字符串数组(因为可变的)

char name[100]; scanf(“%s”, name); // 从name的首字符开始一个一个存放字符串,最后加一个’\0’ 也存放里面。

返回指针的函数:

<span style="font-size:18px;">#include <stdio.h>
char *test();
int main()
{
char *name = test();
printf("name = %s\n", name);
return 0;
}
char *test()   //定义一个名字为test的字符型指针函数。
{
return “rose”; //返回字符串rose
}</span>

指向函数的指针:指针指向函数的地址即可

<span style="font-size:18px;"> #include <stdio.h>
void test()
{
printf("调用了test函数\n");
}
int main()
{
// (*p)是固定写法,代表指针变量p将来肯定指向函数。
// 左边的void代表指针变量p指向的函数没有返回值
// 右边的() 表示变量p指向的函数没有形参

</span>
<span style="font-size:18px;">void (*p)();

</span>
<span style="font-size:18px;">// 指针变量p指向test函数
p = test; //函数名就代表函数的地址
(*p)();  //利用指针间接调用test函数
test();  //直接调用
p();  //间接调用 (共三种方式调用)

return 0;
}</span>





 









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值