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

来源:互联网 发布:wampserver运行php 编辑:程序博客网 时间:2024/05/14 20:55

------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
原创粉丝点击