一、指针的声明
指针的使用通常分两步: 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); //name2和name3指向同一地址 return 0; }
字符串与数组总结: 定义字符串的2种方式 1>利用数组 char name[] = "itcast"; *特点:字符串里面的字符是可以修改的 *适用场合:字符串的内容需要经常修改 2>利用指针 char *name = “itcast”; *特点:字符串其实是一个常量字符串,里面的字符是不能修改的 *使用场合:字符串的内容不需要修改,而且这个字符串经常使用 五、指针数组和字符串输入 保存字符串数组的两种方式: 1、char names[3][10] = {“jack”, “rose”, “tom”}; 2、char *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(); //直接调用函数 } |