黑马程序员技术交流社区

标题: C语言笔记--神一样的指针 [打印本页]

作者: 米匠    时间: 2014-10-11 11:29
标题: C语言笔记--神一样的指针
一、指针的声明

指针的使用通常分两步:
1、int *p = &a;
2、*p = 10;

int main()
{
int a = 10;

int *p = &a;  //声明指针变量,并且把a的地址赋值给指针变量p

*p = 20;  //20赋值给指针p所指向的内存,即a

printf("%d\n", a);
return 0;
}
*p = 20;的时候,也就是把a的值改为了20,因为p指向的是a内存块。

注意:
1、两个*号含义不同,第一个*表示这是一个指针变量,是一个一个标识;第二个*表示指针p指向的内存
2、指针变量只能存储地址
3、指针只能指向和指针相同类型的变量
4、指针所指向的内存块的大小等于指针类型所占的字节数
二、指向指针的指针
int main()
{
int a = 10;
int *p = &a;  //可以理解为int * 就是指针p的类型
int **pp = &p;  //所以指向p的指针必须是int * 类型,声明新的指针为*pp,加上类型就是int **pp
**pp = 20;
printf(“%d\n”, a);  //输出为20
}
三、指针与数组
int main()
{
int ages[5] = {10, 9, 8, 67, 56};
int *p = ages;  //定义一个指针变量指向数组第一个元素的地址,也是指向数组的地址
for(int i=0; i<5; i++)
{
printf(“%d\n”, *(p + i));  //p+i就是数组中i元素的地址,p+i不是正常的算术计算,而是指针p的地址加上指针类型字节数的地址,i的大小取决于指针的类型
printf(“%d\n”, p);  //等同于上面的写法
}
return 0;
}
//---------------------------------------------------------------------------------------------------------
int main()
{
int ages[5];  //ages数组的大小为20个字节
change(ages);  //但是当数组作为参数的时候,传入的是数组的指针
return 0;
}

void change(int *array)  //等同于下面的方法,只不过下面的方法在编译的时候会警告,所以此方法才是接收数组参数的正确写法
{
int s = sizeof(array);
printf(“%d\n”, s);  //所以输出为8
}
/*
void change(int array[])  //此方法编译时候会被警告,所以应该使用上边的方法接收数组参数
{
int s = sizeof(array);
printf(“%d\n”, s);  //所以输出为8
}*/
四、数组与字符串
int main()
{
char *name2 = “it”;  //指针指向的是数组中首元素的地址,即“i”的地址
printf(“%c\n”, *name2);  //输出为 “i”,*name2的意思为指针name2指向地址所在的内存块

printf(“%s\n”, name2);  //name2为数组的地址,也是数组首元素的地址,%s意味着从name2所在地址的内存开始计算,遇到“\0”结束,所以输出为整个字符串,即“it

return 0;
}
C语言内存分为常量区、堆、栈
常量区存放常量字符串
堆存放对象
栈存放局部变量

使用指针声明字符串时,字符串为常量,不可更改,如下:

int main()
{
char *name2 = “it”;
*name2 = ‘T’;  //错误的写法,指针声明字符串不可更改
char *name3 = “it”;  //这里的”it”是常量
printf(“%p\n%p\n”, name2, name3);  //name2name3指向同一地址
return 0;
}

字符串与数组总结:
定义字符串的2种方式
1>利用数组
char name[] = "itcast";
*特点:字符串里面的字符是可以修改的
*适用场合:字符串的内容需要经常修改
2>利用指针
char *name = “itcast”;
*特点:字符串其实是一个常量字符串,里面的字符是不能修改的
*使用场合:字符串的内容不需要修改,而且这个字符串经常使用
五、指针数组和字符串输入
保存字符串数组的两种方式:
1char names[3][10] = {“jack”, “rose”, “tom”};
2char *names[5] = {“jack”, “rose”, “tom”};

int main()
{
char *names[5] = {“jack”, “rose”, “tom”};
printf(“%p\n”, names[0]);  //j”的地址
printf(“%c\n”, *names[0]);  //j”地址的内容
printf(“%s\n”, names[0]);  //输出为“jack
printf(“%c\n”, names[0][1]);  //输出为“a
}
六、返回指针的函数
#include <stdio.h>
char *test();

int main()
{
char *name = test();
printf(“name=%s\n”, name);
return 0;
}

char *test()
{
return “rose”;
}
七、指向函数的指针
void test()
{
printf(“......”);
}
int main()
{
void (*p)();  //定义指向函数的指针,void表示这个指向的函数没有返回值;()表示指向的函数没有参数
p = test;  //函数名就是函数的地址,把函数的地址给p
(*p)();  //通过指针间接调用函数
p();  //同上
test();  //直接调用函数
}

作者: Lxy    时间: 2014-10-11 12:28
1、指针只能指向和指针相同类型的变量
           准确来讲也可以指向不同类型的变量,只是值未知
2、声明新的指针为*pp,加上类型就是int **pp
        好像准确来讲为:声明新的指针变量为pp,加上类型就是int ** pp;
作者: alpha.huai    时间: 2014-10-11 19:30
没有提到泛型指针 void *




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2