嵌入式培训之C语言学习(十五)指针(3)指针与字符串、二维整型数组

一、字符串与指针

(一)指针与一维字符型数组

        推导过程与一维字符型数组相同

        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、计算二维数组边框和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值