指针
scanf函数
使用scanf("%d",&N) 将从用户的输入中读入到变量N的地址中,&是取N的地址。
假如没有了&,也就是是将用户输入读入到变量N的内容所指的地址中,这一个地址可能是一个垃圾数,或者你定义的一个整数如100,编译器需要将用户输入存入到内存地址为100的地址这肯定是错的
用scanf函数给数组赋值格式是这样的
for(i=0;i<len;i++) scanf("%d",&a[i])
打印指针变量所指向的内容
#include <stdio.h> #include <stdlib.h> int main() { printf("Hello world!\n"); int n=1000; int *p=&n; printf("%p\n",p); printf("%p\n",&n); }
指针作为函数参数
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { printf("Hello world!\n"); int n=1000; int *p=&n; p=10; printf("p所指的内存地址%p\n",p); printf("%p\n",&n); p=-10; printf("给指针赋值负数,尽管内存地址没有负数,当时这样赋值是没有问题的\n"); printf("p所指的内存地址%p\n",p); int a=10;int b=20; printf("\n变量a所在的内存地址%p\n",&a); printf("变量b所在的内存地址%p\n",&b); int *p1=&a; //下面语句是直接改变指针的指向,但是编译器不会报错 printf("\n赋值前p1所指的内存地址%p\n",p1); p1=10; printf("赋值后p1所指的内存地址%p\n",p1); printf("这里说明了指针p1作为一个变量其值是可以改变的\n"); // 但是要是往这个地址写东西,编译会通过当时程序会崩溃 // *p1=100; swap2(&a,&b); printf("a=%d b=%d\n",a,b ); } void swap(int *x,int *y) { //函数定义为 int*x,也就是说x是一个指针,x的内容就是一个地址 //*x就是x这个地址所存的内容 // 通过gdb> p x 确实看到了 $1 = (int *) 0x28ff00 //> p *x $2 = 10 int temp; temp=*x; *x=*y; *y=temp; } void swap1(int *x,int *y) { // int *Ptemp; //这样写编译器不会报错,但程序会崩溃,因为使用了没有指定的指针 //下面的编译器不会报错,但程序会崩溃,因为你要往空地址放东西 int *Ptemp=NULL; *Ptemp=*x; *x=*y; *y=*Ptemp; } void swap2(int *x,int *y) { //这个程序不起作用因为这里只是调转了xy的指向 //原来x指向a,y指向b 但后来是x指向b,y指向a printf("x指向%d\n",*x ); printf("y指向%d\n",*y ); int *ptemp; ptemp=x; x=y; y=ptemp; printf("x指向%d\n",*x ); printf("y指向%d\n",*y ); }
任何的类型都可以作为数组或指针的类型 ,如int long float …………
特别的当用用数组作为指针的基类型就是 指向数组的指针
定义为 int(*p)[3] ----------首先是p与*结合定义了一个指针,了一个指向int型数组,数组内有三个元素即 int [3]
<=>指向一个有3个元素的一维数组的指针变量
现在还不知道指向数组的指针的用处
当用指针作为数组的基类型,就是指针数组,即数组的每一个元素的类型都是指针类型。
定义为 char *p[3]----------因为p首先是与 [3] 结合,成为一个数组,然后是基类型为char * 即指针类型
指针与二维数组
用另一个角度看二维数组
int a[2][3] 看成是一个复合的一维数组,这个数组有两个元素,每一个元素都是 int [3]类型, 铜鼓 a[i] i=0,1,2,…………访问第i个元素 数组是复合类型,必须转化为基本类型才能访问对应的值 a[i] +j 就是对应的基本类型的地址,也就是第i行,第j列的地址 通过解引用 *(a[i]+j)就可访问对应元素的值
定义二维数组的指针
int *(p)[3]
#include <stdio.h> #include <stdlib.h> int main() { printf("Hello world!\n"); int count=1,i,j; int a[2][3]; for(i=0;i<2;i++) for(j=0;j<3;j++) { a[i][j]=count; count++; } for(i=0;i<2;i++) { for(j=0;j<3;j++) { printf("%d\t",a[i][j]); } printf("\n "); } printf("\n "); printf("\n下面两个说明用数组名a表示了二维数组的首地址,也就是第0行的地址\n"); printf("二维数组首地址 %p\n",a); printf("二维数组第0行首地址%p\n",a[0]); printf("\n "); printf("\na+i就是指二维数组a的第i行的首地址,要访问第i行第j列的元素,需要得到对应的地址为*(a+i)+j\n"); printf("二维数组第一行第一列地址 %p\n",a[1]+1); printf("二维数组第一行第一列元素 %d\n",*(a[1]+1)); printf("%p\t",*a); printf("%p\t",a[0]); return 0; }