段错误,无效空地址的指针的引用会发生错误。
const指针,
const int *p 与int* const p 区别:
前者是固定了指针所指地址内存中的数据不可变
后者是固定了指针地址不可变。
限制p,即固定了地址。
限制了*p就固定了数据。
野指针,地址有效但无可用数据。
*p++ = j+i;给指针*p赋值。
数组就是指针:(之间也有很大的区别,指针没有内存空间来存放数据,数组有内存空间可以存放数据)。
array[]是一维数组;
p = array;//p = &array[0]
int array[5];
array = array[0];
array[4] = *(array+4);
指针的下标形态:
int* p;
array[4] = p[4];
指针排序:
int flag = 0;
for(int i = 0;i<n;i++){
for(int j = 1;j<n-i;j++){
if(*p<*(p+j)){
flag = *p;
*p = *(p+j);
*(p+j) = flag;
}
}
printf("array[%d] = %d \n",i,*p);
p++;
}
指针+内存+char数组:
http://blog.csdn.net/iamfranter/article/details/6826248
指针与数组的区别:
指针能做的数组不一定能做;
数组能做的指针不一定能做:
char aa[] ="you are bad";
// aa = "ou";(/*wrong*/)
char ab[12] ="you are bad";
// ab = "ou";(/*wrong*/)
//上面的数组aa/ab数组不能像下面的指针“ac”这样应用,因为数组在创建时指针(aa/ab)的地址
//已经被绑定到被分配的内存地址,所以不可以再变动
char* ac =NULL;
ac = "you are bad";
// ac[0] = 'o';这个复制表达式能否完成依靠编译器,如果编译器允许就可以
ab[0] ='o';//通过;
添加头文件:#include<stdlib.h> free(viod);释放指针。
指针与数组的区别:
char* p = “hello”;
p[0] = ‘X’;//不能成功赋值:编译器不会觉得没有什么不妥,但是表达式企图改变常量值是不能够通过的。
char a[] = “hello”;
a[0] = ‘X’;//成功,这是数组的赋值,与指针相比,指针不会被分配内存,而数组可以被分配内存。所以 a[0] = ‘X’成功编译。
char数组的比较不能用“==”或“!=”,要用strcmp();而且赋值不能用a = b;而是要用:strcp(a,b);(把b赋值给a)。
计算内存容量sizeof(int);
char* p = “123”;
对strlen的掌握,它没有包括字符串末尾的’\0'。
char chr[3];
strcpy(chr,p);//出错,strcpy在为把“123”复制到chr之后结束时会把结束标示“\0”作为一个元素添加到chr中,如果chr的元素不够,便会出错。
而且如果一个数组中被重新全部赋值后(包括\0位),strcp()方法在操作时若是找不到“\0”标示符,strcpy会一直赋值下去,即便被赋值数组越界。
野指针:野指针不能够被使用,不可以被赋值。//int *p; *p = *pn; 或*pt = *p;都是不被允许的,因为野指针有可能指向系统区,而系统区的数据是不可以被更改的。
数组指针的使用。
#include<stdio.h>
#include<stdlib.h>
#include"time.h"
int main(){
char *p[5] = {NULL};
srand((unsigned)time(NULL));
0. //sum取1-10之间的整数;
int i,sum = rand()%10+1;
for(i = 0;i<sum;i++){
1. //给每个元素申请内存空间
p[i]=(char *)malloc(sizeof(char)*100);
2. //检查每个指针的值是否位NULL,NULL不可被使用(用来存储数据);
if(p[i]==NULL) break;
else scanf("%s",p[i]);
}
for (i=0; i<sum; i++) {
printf("%s\n",p[i]);
}
for(int i = 0;i<5;i++){
3. //指针数组使用完毕需要被释放内存
free(p[i]);
4. //被释放内存的指针数组需要被置空:NULL,防止产生野指针。
p[i] = NULL;
}
return 0;
}
内存分配:
内存的静态存储区:常量(值不可被修改)
栈上分配:局部变量(生存周期短,不可被return使用。)
堆上非配:user申请的,亲自申请的内存存储空间需要手动释放,要不然会造成内存泄露,而且释放之后的指针要置为NULL,要不然会生成野指针。
p+=6; p = p+6;
函数参数不超过4个。
数组指针:
#include<stdio.h>
#include<stdlib.h>
#include"time.h"
int main(){
int carray[2][5] = {2,6,8};
//int [5] carray[2];
//int [5] *pp;
int (*pp)[5] = NULL;
pp = carray;
//*pp = &carray[0];*(pp+1) = &carray[1];
printf("%d",*(carray[0]+1));
//看懂就懂了。
//pp = carray;
//carray默认等于carray[0]地址。
//*pp = carray = carray[0]
//*(pp+1) = carray[1]
//*pp+1 =carray[0]+1 = carray[0][1]
return 0;
}
详解:
*pp:指针变量指向内存中的数据
&pp:指针变量的地址
pp:指针变量所指向的地址(存储的地址)。
二位数组作为函数参数,a[][5]中的5不可少。否则报错。
数组指针PK指针数组?
数组指针:int (*p)[5]
可写成: int[5] *p
指针*p是一个指向数组int[5]的指针
指针数组:int* p[5]
一个包含5个指针的数组。
使用指针数组的元素来遍历数组元素。
#include<stdio.h>
#include<stdlib.h>
#include"time.h"
int main(){
int array[10] = {2,5,6,4,7};
int *parray[5] = {NULL,NULL,array+1};
//printf("parray[0] = %p",parray[0]);
for(int i= 0;i<5;i++){
printf("%d\n",*(parray[2]+i-1));
}
for(int i = 0;i<5;i++){
parray[i] = (int*)malloc(sizeof(int)*100);
}
for(int i = 0;i<5;i++){
free(parray[i]);
parray[i] =NULL;
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include"time.h"
int main(int a,char* arg[]){
// printf("%c\n",arg[1][2]);
// printf("%c\n",*(arg[2]+0));
// printf("%c\n",*(arg[2]+1));
//从arg[2]所指向字符串的第二个元素开始输出,直到结尾
printf("arg[2]+2 = %s\n",arg[2]+2);
//输出的时arg[2]所指向字符串的第二个元素。
printf("*(arg[2]+2) = %c\n”,*(arg[2]+2));
//从arg[3]所指向的第二元素开始输出,直到结尾
printf("arg[3]+2 = %s\n",arg[3]+2);
char arr[20] = "you are SB";
arg[4] = arr;
printf("arg[4]+4 = %s\n",arg[4]+4);
printf("arg[0]+132 = %s\n",arg[0]+132);
int array[10] = {2,5,6,4,7};
return 0;
}
使用指针数组:
可以选择从数组的某个元素开始遍历输出。
也可以输出单个数组元素。
一个指针数组的每一个元素可以用来遍历任意一个数组。
int main(){
char* array[5] = {NULL};
char a[] = "youno1";
array[0] = a;
//指针的形式:
printf("%c\n",*(array[0]+1));
//数组的方式:
printf("%c\n",a[1]);
//指针下标的方式:
printf("%c\n",array[0][1]);
}