1.字符串的拷贝strcpy
基本知识点
Strcpy(字符数组1,字符串2)
1.strcpy该函数是通过第二个参数的字符串的结束符来判断是否拷贝结束的;
2.strlen函数得到字符串的长度,是不包含字符串结束符的;
3.使用strcpy函数的时候,一定要注意第一个字符数组的大小至少不小于字符串2的大小,否则便是访问越界;
4.字符串2后面的`\0`也一同被复制到字符数组1中;
程序错误分析
程序片段一:
void test1()
{
char string[10];
char* str1="0123456789";
strcpy(string, str1);
}
这里string数组越界,因为str1字符的长度是10,还有一个结束符‘/0’。所以总共有11个字符长度。而string数组大小为10,所以就越界了。
PS:使用strcpy函数的时候一定要注意前面目的数组的大小一定要大于后面字符串的大小,否则便是访问越界。
程序片段二:
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10;i++)
{
str1[i] ='a';
}
strcpy(string, str1);
}
这里最大的问题还是str1没有结束符,因为strcpy的第二个参数应该是一个字符串常量。该函数就是通过判断第二个参数的结束符来判断是否拷贝结束的。所以在for循环后面应加上str1p[9] = '/0';
PS:字符数组和字符串的最明显的区别就是字符串会被默认的加上结束符‘/0’。
程序片段三
void test3(char* str1)
{
char string[10];
if(strlen(str1)<=10)
{
strcpy(string, str1);
}
}
这里的问题仍是越界问题。strlen函数得到字符串的长度,是除结束符之外的。如果str字符串的长度正好等于10的话,就很明显越界了。
2.第2题: 考查指针, 这道题只适合于那些特别细心且对指针和数组有深入理解的人
main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1) ;
printf("%d %d" , *(a+1) , *(ptr-1) ) ;
}
这段程序的输出是:
(a) 2 2
(b) 2 1
(c) 2 5
(d) 以上均不是
我在想,用什么样的方式才能很好解释指针偏移这个问题,想到一点就是:你需要判断这个指针到底是一个什么类型,我们通过指针类型就可以轻松算出偏移大小。
做题的时候一定要搞清楚x的基本类型是什么!!!!
比如上面的:
a的类型是一个整形数组,它有5个成员。
&a的类型是一个整形数组的指针,所以&a+1指向的地方就是等同于a[6];
既ptr就相当于a[6],ptr的基本类型就是一个int的数组值,所以ptr-1.就是指向a[5]的指针。
我在想,用什么样的方式才能很好解释指针偏移这个问题,想到一点就是:你需要判断这个指针到底是一个什么类型,我们通过指针类型就可以轻松算出偏移大小。
3.第3题: 考查指针数组
int main()
{
int a[][3] = { 1,2,3 ,4, 5,6};
int (*ptr)[3] =a;
printf("%d %d " ,(*ptr) [1], (*ptr)[2] );
++ptr;
printf("%d %d" ,(*ptr) [1], (*ptr)[2] );
}
这段程序的输出是:
(a) 2 3 5 6
(b) 2 3 4 5
(c) 4 5 0 0
(d) 以上均不对
ptr是一个数组指针,这个数组有三个int的成员。
数组指针:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
指针数组:
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。