1:
/*
变量能够使用,就要在计算机中存储起来;
*/
int main(int argc, const char * argv[]) { int a=10;//栈上的四个字节; //&取地址符,&a表示a的地址 printf("a的地址是:%p\n",&a);//打印a的地址 a的地址是:0x7fff5fbff81c //*间接寻址符 printf("a的地址上的值是:%d\n",*(&a));//打印a的值 a的地址上的值是:10 return 0; }<span style="color:#e32400;"> </span>
2:
/*
指针:存储变量的地址的一种变量;
指针定义: int *p;// *是指针标识,说明p是指针名,int表示指向的数据类型,或者说p保存的是一个int型变量的地址;
*/
int main() { int *p;//*只是指针标识 int a=10; int b=20; p = &a;//p可以保存一个int型数据的地址;a是一个int,所以p就可以保存a的地址;如果p保存a的地址,就说明p指向a; printf("p=%p,&a=%p\n",p,&a); printf("*p = %d\n",*p);//p指向的内容; *p = 100;//通过地址,修改了地址上的内容;*间接寻址符,取出p地址里的内容; printf("a=%d\n",a); p = &b;//p的值变了;p指向的数据变了;p指向了另一个数据; *p = 200;//修改了指向的内容,b被修改; printf("a=%d,b=%d\n",a,b); return 0; }
int main() { int a=10; int *p = &a;//int *p;*是指针标识,int * 只是说明了p得类型;等价于 int *p ;p=&a; printf("%d\n",*p); int *q;//定义了一个指针变量,如果没有指向就是任意的,*q操作可能会异常;指针也要先赋值,后使用(告诉指针指向哪个变量) // *q = 100; printf("*q=%d\n",*q); return 0; }
int main() { int *p; // char *q;//其他的指针类型 // long *w; printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8 printf("sizeof(int *)=%lu\n",sizeof(int *));//sizeof(int *)=8 printf("sizeof(char *)=%lu\n",sizeof(char *));//sizeof(char *)=8 printf("sizeof(long *)=%lu\n",sizeof(long *));//sizeof(long *)=8 printf("sizeof(double *)=%lu\n",sizeof(double *));//sizeof(double *)=8 //各种指针类型在内存中占有的内存都是一样的,在64位系统下都是8字节; return 0; }
3:
/*
指针的运算 ++, --, +, -
地址的运算;
*/
int main() { int a[] = {1,2,3,4,5};//a是数组名,里面保存的是数组首个元素的地址,也就是a=&a[0]; int *p;//p可以保存int型数据的地址;a里面有5个int,p可以指向里面任何一个元素; //p指向第一个元素a[0]? p = &a[0];//等价于p=a; printf("p = %p\n&a[0] = %p\na = %p",p,&a[0],a);//p = 0x7fff5fbff810 &a[0] = 0x7fff5fbff810 a = 0x7fff5fbff810 p++;//p向后偏移了一个int的距离,就是4个字节=p指向的数据类型的大小; printf("\np = %p\n *p=%d\n",p,*p);//p指向了a[1] p = 0x7fff5fbff814 *p=2 p = a; for (int i=0; i<5; i++)//1 2 3 4 5 { printf("%d ",*p); p++; } p = &a[4]; for (int i=0; i<5; i++)//5 4 3 2 1 { printf("%d ",*p--); } return 0; }
int main() { int a[]={1,2,3,4,5}; int sum = 0; int *p = a; p++;//p指向a[1]; printf("%lu\n",p-a);//地址1-地址2:表示两个地址之间可以放几个指向的数据的类型,放几个int; 1 printf("%d \n",*(p-1));//地址-一个数,是一个地址,就是指针往前偏移 N*N个指向的数据类型; 1 p = a; //通过p+i来遍历数组;p+i = &a[i] ,*(p+i) = a[i]; for(int i=0;i<5;i++)//1 2 3 4 5 { printf("%d ",*(p+i)); } p = &a[4]; for(int i=0;i<5;i++)//5 4 3 2 1 { printf("%d ",*(p-i)); } p = a; for(int i=0;i<5;i++) { sum += *(p+i); } printf("\nsum = %d\n",sum);//sum = 15 return 0; }
4:
/*
野指针
*/
int main() { int *p;//只定义,没有赋值,指向是任意的,就是野指针; printf("p=%p\n",p); *p = 100;//修改了不确定的东西;禁止使用,禁止这样操作,低级错误; return 0; }
5:
/*
空指针:如果p的值=NULL,p就是空指针;
NULL是个非法地址; *p既不能读,也不能写;
指针使用前必须判空;
*/
int main() { int *p = NULL; printf("p=%p",p); // printf("*p=%d\n",*p);//错误,程序出错 if(p == NULL) { printf("p是个空指针不能使用\n"); } else { printf("p合法\n"); } }
6:
/*
void * 指针,通配型指针,可以指向任意的数据类型,但是在使用时要注意强制转换成指向的类型;
*/
int main() { void *p; char ch = 'a'; int i=1234; double b=12.38; printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8 p = &ch;//p指向char型的变量 // printf("%c\n",*p);//编译失败,类型不匹配; printf("%c\n",*(char *)p);//(char *)是类型说明; a p = &i; printf("%d\n",*(int *)p);//1234 p = &b; printf("%lf\n",*(double *)p);//12.380000 return 0; }
void swap(int a,int b)//只是形参传递,函数结束即销毁,达不到交换的目的 { int temp = a; a = b; b = temp; } void swap_true(int *a,int *b)//地址传递,操作的任然是地址内存储的值,可以达到交换目的 { int temp = *a; *a = *b; *b = temp; } int main() { int x=10,y=20; swap(x,y); printf("x=%d,y=%d\n",x,y);//x=10,y=20 swap_true(&x,&y); printf("x=%d,y=%d\n",x,y);//x=20,y=10 return 0; }
7:
/*
数组和指针
数组作为函数的入参传递的时候
形式参数和实际参数都可以是指针形式或者是数组形式;
*/
void setArray(int a[],int len)//形式参数是数组形式 { // printf("sizeof(a)=%lu\n",sizeof(a));//结果为8 a就是个指针,8个字节,只能传递数组的首地址,不能传递元素的个数 for(int i=0;i<len;i++) { a[i]=100; } } void printArray(int a[],int len)//形式参数是数组形式 { for(int i=0;i<len;i++) { printf("%d ",a[i]); } } void setArray1(int *a,int len)//形式参数是指针形式 { //a[0]=*a &a[0]=a a[i]=*(a+i) for(int i=0;i<len;i++) { *(a+i)=10; } } int main() { int a[5] = {1,2,3,4,5};//a是数组名,保存数组的首地址;数组的名字a可以看成是常量指针; int *p = a;//p只能指向一个int,指向一个元素,不能指向一个数组;这里p指向的是数组首地址 setArray(a, 5);//实际参数是数组形式 printArray(p,5);//实际参数是指针形式 setArray1(p,5); printArray(p,5); printf("%d\n",*(a+2)); return 0; }
8:
/*
数组和指针的总结
1:数组作为函数的入参传递的时候
形式参数和实际参数都可以是指针形式或者是数组形式;
形参是数组的时候,其实本质是已经完全是指针变量;
setArray(int a[],int len)
这个里面,a就是指针,不能根据它计算元数组元素的个数
这个里面,a是个变量,可以被赋值,a++是允许的;
2:数组名可以看成是常量指针(指向首个元素的常量指针); 保存数组的首个元素的地址;
int a[5];
此时a不能被赋值,a++就是错误的;
a[i] = *(a+i) = *(p+i)
*/
//用指针传递数组,进行排序 void sortArray(int *p,int len)//排序 { for(int i=0;i<len-1;i++) { for(int j=0;j<len-i-1;j++) { if(*(p+j) > *(p+j+1)) { int temp = *(p+j); *(p+j) = *(p+j+1); *(p+j+1) = temp; } } } } void printArray(int *p,int len)//打印 { for(int i=0;i<len;i++) { printf("%d ",*(p+i)); } } int printMax(int *p,int len)//找最大值 { int max = *p;//定义最大值为数组第一个元素 for(int i=0;i<len;i++) { if(max < *(p+i)) { max = *(p+i); } } return max; } int main() { int a[] = {43,54,32,1,43,67,543,6578,867,64,53,2}; int len = sizeof(a)/sizeof(a[0]); sortArray(a, len); printArray(a,len); printf("\nthe max is %d\n",printMax(a,len)); return 0; }
9:
/*
字符数组和指针
*/
/*
常量字符串和字符数组的差别;
常量字符串不能改;
字符数组可以改,字符数组必须要有自己的空间;
*/
int main() { char str[100]="helloworld";//常量字符串给变量字符数组赋值; char *p = "helloworld";//p指向常量字符串,不能通过*p去修改常量字符串;p指向常量字符串里的'h' // *p = 'H';//不可修改,p指向常量区,只读,不可写; printf("%s\n",p); str[0] = 'H';//str的元素都是char型变量;如果要修改字符,就需要定义成数组形式; printf("%s\n",str); return 0; }
<span style="color:#ff0000;">//通过指针来传递字符数组,不需要传递数组的长度;因为在做字符串处理的时候,字符串本身到'\0'结束</span> //把小写字母改成大写 #include <string.h> void convert(char *s)//将小写字母改成大写字母 { printf("in convert s is %s\n",s); int len = (int)strlen(s); for(int i=0;i<len;i++) { if(*(s+i)>='a' && *(s+i)<='z')//如果是字母的话就转换 { *(s+i) -= 'a'-'A'; } } } char * convert(char *s)//一般字符数组需要返回价值 { char *p = s; while(*p)//当*p不等于0的时候进入循环 { if(*p>='a' && *p<='z') { *p -= 'a'-'A'; } p++; } return s; } int main() { char str[100]="helleworld"; convert(str); printf("in convert s is %s\n",str); return 0; }
10:
/*
"hello"-->"heLLo"替换的目标是给定的 l-->A
replace(char *s,char old,char new)
*/
char *replace(char *s,char old,char new) { char *p = s; while(*p) { if(*p == old) { *p = new; } p++; } return s; } //计算字符串的长度,实现strlen的功能; int myStrlen(char *s) { char *p = s; int count=0; while(*p) { count++; p++; } return count; } int main() { char str[100] = "helloworld"; replace(str,'l','Y'); printf("%s \n",str); int len = myStrlen(str); printf("%d \n",len); return 0; }
//字符串里面插入一个字符
//pos表示插入的位置,ch表示插入的字符;
char *insert(char *s,int pos,char ch) { int len = (int)strlen(s); char *p = s; int count=1; while(*p)//当*p不等于0的时候进入循环 { if(pos == len+1)//如果需要插入的元素的位置是字符数组的最后一个位置,也就是'\0'处的时候直接将原'\0'处赋值为目标字符,然后退出循环 { *(s+len) = ch; break; } if(pos == count)//如果插入的位置为数组中间任意位置的时候进入判断 { for (int i=len-1; i>=pos-1; i--)//将数组插入位置(包括插入位置)之后到'\0'之前的所有元素往后移位 { *(s+i+1) = *(s+i);//也就是'\0'之前的第一个元素移位到'\0'位置,依次类推 } *(s+pos-1) = ch;//将原数组中移动的最后一个元素赋值为需要插入的字符; break; } count++; p++; } return s; } int main() { char str[100]="helloworld"; insert(str,1,'M'); printf("%s \n",str); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/throneman/article/details/48101699