一、字符串与指针
(一)指针与一维字符型数组
推导过程与一维字符型数组相同
char s[]="hello";
char *p = s;
可以用来存放字符串;
(二)指针与字符串
字符串在c语言中是按照字符数组的形式存在,而字符串常量是存储在字符串常量区的。
处理字符串的形式:
(1)char s[] = "hello";
这句代码表示数组s在栈上开辟一块空间,用字符串常量中的 "hello"进行初始化
(2)const char *p = "hello";
这句代码表示p指向了字符串常量区中的 "hello",因为是指向了字符串常量区,所以只
能做读取操作,不能修改。
(三)const关键字
1、作用:通过在指针前加const关键字表明此后无法通过该指针去修改它指向的变量。
2、(1) int *p;
int a = 10;
const int *p = &a;
此时const限定的是基类型,就是说不能通过 *p =其他类型的数据赋值的方式修改基类
型数据;
(2) int const *p = &a;
这句代码的作用和上面的代码的一样;
(3) int * const p = &a;
此时const限定是指针变量p ,表示将p限定为只读,不能做修改;
(4)const int * const p = &a;
此时是基类型和指针变量都被限定为只读,既不能通过*p修改基类型数据,也不能修改
指针变量p;
(5)const char*p = "Hello World!";
指针变量p指向‘H’,接收的是H在字符串常量区的地址;
sizeof(p) = 8 strlen(p) = 13
3、注意事项:
(1)const关键字加上参数种类适应性更好(没加只能传数组名,加上也可传字符型常量);
(2)在指针变量前加const指针变量可以被赋值,但无法通过该指针去修改它指向的变量;
(3)加不加该关键字取决于功能上是否对空间内容做出修改(C语言中最好加上const关键字,加上不加好)。
(四)补充
1、sizeof()中,()后既可以填变量名也可以填类型名;编译器在编译时,会将变量名
换成类型名;
2、字符串常量区的内容不能被修改
char *p = "Hello World!";
*p = 'A';//*p为‘H’本尊(指针的间接访问)在栈区,而p指向字符串常量区
Puts(p);
运行结果:程序崩溃
char s[100] = "Hello World!";
char *p = s;
*p = 'A';
puts(p);
输出结果:Aello World!
3、考点:在字符串常量区一样的字符串存一份
const char *p1 = "China";
const char *p2 = "China";
puts(p1 == p2 ? "Yes" : "No");//p1与p2比的是地址
运行结果:Yes
若const char *p1 = "China!";则运行结果为No。
(五)用指针实现字符串的相关函数
1、puts函数:
2、strlen函数:
3、strcpy函数:
4、strcat函数:
5、strncpy函数:只复制源中的前n个字符,但遇'\0'结束
6、strncat函数:只拷贝源中的前n个字符,但遇'\0'结束
7、strcmp函数:
8、strncmp函数:只比较源中的前n个字符,但遇'\0'结束
(六)万能指针
(1)void * 表示空类型的指针,是万能指针,能够接收来自任何类型的变量地址;
(2)万能指针不能作为指针进行指针运算;
(3)用于强转与设计者不知道用什么类型的地方;
short i = 10;
void *p;
p = &i;
printf("%d\n",(*(short *)p));//运行结果为i的值
(七)内存拷贝函数(memcpy函数)
1、函数原型
void *memcpy(void *dest,const void *src ,size_t n)
2、代码实现:
(八)练习
编写程序在一个字符串中查找某个字串首次出现的位置, int subString(const char *s, const char *sub);
二、二维整形数组与指针
(一)指针数组与数组指针
1、指针数组:存放指针变量的数组
int *p[10];//其中int *为数据类型,p[10]为数组(数组不可被整体引用);
定义了10个指针变量
printf("%lu\n",sizeof(p));//输出结果为80(占80个字节)
2、数组指针:指向整个数组的指针
int (*p)[10];//一个指向长度为10的一维整型数组的指针
p = &a;//在指针变量p中保存长度为10的一维整型数组的地址;p与p+1差40个字节
3、区分:以 int a[3][4] = {1,2,...,11,12}为例
1、表达式a: a <=> &a[0] //a二维数组名,指向数组的指针,
对应的数据类型:int(*)[4],指针+1(跨16个字节)
2、表达式a[0]:a[0] <=> &a[0][0] //表达式数据类型:int * ;指针+1(跨4个字节)
3、表达式&a:数据类型:int (*)[3][4],指向二维数组的指针,指针+1(跨48个)
4、a[i][j] <=> *(*(a + i) + j)
5、考点:
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4];
p = a;//指向a[0]的指针
printf("%d\n", *((int *)(p + 3) - 3));//运行结果为10
(二)例题
1、求二维数组元素最大值
2、计算二维数组边框和