C语言第七天

day7:

int a[3]={1,2,3};

int *p=a;

*p++:先取p的内容:1 再++(p++)---->1

(*p)++:先取p的内容:1,再++((*p)++)---->1

++*p:先取p的内容:1, 再++((*p)++)----->2

++(*p):先取p的内容:1, 再++((*p)++)----->2

一、关系运算:> < >= <= !=

指针的关系运算:指向高地址的的指针大于指向低地址的指针

char s[10]="hello";

char *p1=&s[1];

char *p2=&s[4];

p1 < p2

关系比较:同数组之间进行比较

二、指针大小:

指针的大小取决于:操作系统 32位---->4字节 64位--->8字节

总结:

1. 32位操作系统,指针大小4字节,64位操作系统,指针大小8字节

2. 内存地址是固定的,但是变量的地址不固定的,(栈区变量(局部变量)随机分配)

3. 指针类型根据指针指向空间的数据类型而决定的

练习:

将字符串转换成整型数字输出。用指针实现

要求:字符串为0-9组成,输出数据为一个整形数

Eg:char s[10]="123”;printf(“%d\n”,num);//num=123;

char s[32]="12345";
    char *p=s;
    int num=0;
    while (*p!='\0')
    {
       num= num*10+*p-48;
       p++;
    }
    printf("%d\n",num);

三、段错误:

产生的原因:1、野指针 2、内存泄露

1、野指针

解决:int *p=NULL; p=&a;

2. 指针p被free(释放 )之后,没有置NULL,会让人以为p是合法指针 然后拿它来用

解决:p=NULL;

2、内存泄露 非法空间操作

四、指针修饰符:

1. const常量化

readonly:只可以读 不能修改

(1)修饰变量

const int a=10;---->int const a=10;

(2) 修饰指针:修饰*p

int a=10;

const int *p=&a;----》int const *p=&a;

修饰p:int * const p1=&b;

修饰*p和p:int const * const p1=&b;

练习:去掉字符串头尾的空格(紫光云数)

示例:输入" test ",输出为"test"

2. void空

(1)不可以修饰变量

void a=10;错误

(2) 修饰指针

int *p=&a;

void *p;//任意类型的指针

强制转换:把任意类型的指针转换成存储的类型

(要转换的类型)p

五、大小端:

大端存储:在地址存储字节数据,在地址存储字节数据

小端存储:在低地址存储低字节数据,在高地址存储高字节数据

一个字节:二进制的数 存储8位

整数:4个字节 ---->32位

十六进制的数据 ---->4位二进制表示--->两个十六进制的数就是8位=1字节

4字节=8个十六进制的数据

int a=0x12345678 起始地址:0x100

0x100

0x101

0x102

0x103

大端

0x12

0x34

0x56

0x78

小端

0x78

0x56

0x34

0x12

六、 二级指针

一级指针:存储变量的地址

二级指针:存储一级指针的地址

格式:存储类型 数据类型 **指针变量;

例:int**p;//二级指针

int a=10;
int *p1=&a;
int **p2=&p1;

地址:

取a的内容: a *p1 **p2

取a的地址: &a p1 *p2

访问p1的地址: &a p1 *p2

七、 指针和数组

指针和二维数组:

直接访问:

二维数组的数组名a:第一行的首地址

如何表示第一行的其他元素呢?---可以降级 降级到第一行第一列的地址 使用*

*a:第一行第一列的地址

*a+1:第一行第二列的地址

访问数组元素的地址(a[i][j]):

&a[i][j] *(a+i)+j a[i]+j

访问数组元素(a[i][j]):

a[i][j] * (*(a+i)+j) *(a[i]+j)

数组指针:

定义:本质是指针 指向数组(行指针)

格式:存储类型 数据类型 ( * 数组指针名)[列数](一行的列数);

例:int a[2][2]={1,2,3,4};

int (*p)[2]=a;//定义一个数组指针p

p:第一行的首地址 p+1:第二行的首地址

p+1:移动8个字节(列数2*数据类型的大小)

间接访问:

访问数组元素的地址(a[i][j]):

&p[i][j] *(p+i)+j p[i]+j

访问数组元素(a[i][j]):

p[i][j] *(*(p+i)+j) *(p[i]+j)

数组指针的大小p:八个字节

sizeof(数组指针名)

和操作系统有关:64----8 32----4

练习:

Int a[2][3]={1,2,3,4,5,6};用数组指针遍历二维数组。

10.设有程序段:char s[7]=”china”; char *p ; p=s ;则下面叙述正确的是 。

A)s和p完全相同

B)数组s中的内容和指针变量p中的内容相等

C)s数组长度和p所指向的字符串长度相等

D)*p与s[0]相等

答案:D

12.以下说明不正确的是 。

A)char a[10]=”china” ;

B)char a[10],*p=a; p=”china”;

C)char *a; a=”china” ;

D)char a[10]; a=”china”;

答案:D

11.若有以下定义:int a[2][3]={2,4,6,8,10,12};则a[1][0]的值是_8___. *(*(a+1)+0)的值是____8___.

19.若有程序段:int a[2][3],(*p)[3]; p=a;则对a数组元素地址的正确引用是 C

A)*(p+2):越界 B)p[2] :越界 C)p[1]+1: D)(p+1)+2:行地址 越界

18.若有定义:int a[2][3];则对a数组的第i行第j列元素地址的正确引用是 D

A)*(a[i]+j) :内容 B)(a+i):地址 第i行的地址 C)*(a+j):第j行的第一列的地址 D)a[i]+j:

17.若有定义:int a[2][3];则对a数组的第i行第j列元素值的正确引用是 A 。

A)*(*(a+i)+j) B)(a+i)[j] C)*(a+i+j) D)*(a+i)+j

[ ]: 先移动j 再降级

16.若有定义:int a[5],*p=a;则对a数组元素地址的正确引用是D

A)p+5:越界 B)*a+1 :内容 C)&a+1 :整个数组的地址 D)&a[0]

指针数组:

定义:本质是数组 里面存放都是指针(地址)

格式:存储类型 数据类型 * 指针数组名[元素的个数]

例:int *arrp[3];

1. 用于存储普通变量的地址

int a=10,b=20,c=30;

int *arrp[3]={&a,&b,&c};

访问a的地址:arrp[0]

a的值:*arrp[0]

访问b的地址:*(arrp+1)

b的内容:**(arrp+1)

2.存放二维数组每一行第一列的地址

int a[3][3]={1,2,3,4,5,6,7,8,9};

int *p[3]={a[0],a[1],a[2]};

访问:

第二行第一列的地址:p[1] *(p+1)

第三行第二列的元素:*(p[2]+1) *(*(p+2)+1)

2. 存放多个字符串

char *p[3]={"hello","abc","ak"};

打印:hello字符串

printf(“%s”,p[0]);

printf(“%s”,*p);

打印:k字符

printf(“%c”,*(p[2]+1));

printf(“%c”,*(*(p+2)+1));

printf(“%c”,p[2][1]);

命令行参数:

int main(int argc, char const *argv[])

{

return 0;

}

argc:字符串的个数 传递的数据的个数

argv:指针数组 存放字符串

int main(int argc, char const *argv[])
{
printf("argc=%d    argv[0]=%s   argv[1]=%s\n",argc,argv[0],argv[1]);
    return 0;
}

练习:

输入一个字符串获取字符串中a字符首次出现的下标(指针做)

char s[32] = {};
    scanf("%s", s);//123aaa
    char *p = s;
    int num=0;
    while (*p!='a')//*p!='\0'
    {
       num++;
       p++;
    }
    printf("%d\n",num);

字符串倒置(用指针实现)

已知字符数组a[10]和b[10]中元素的值递增有序,用指针实现将两个数组中元素按照递增顺序输出。

如:char a[10]=”acdgjmno” ; char b[10]=”befhil”;->”abcdefghijlmno”

#include<stdio.h>
int main(int argc, char const *argv[])
{
char a[10]="acdgmo";
char b[10]="befh";
char *pa=a;
char *pb=b;
while (*pa &&*pb)
{
    if (*pa<*pb)
    {
        printf("%c ",*pa);
        pa++;
    }else{
         printf("%c ",*pb);
        pb++;
    }   
}
if (*pa=='\0')
{
  printf("%s",pb);
}else{
      printf("%s",pa);
}
       return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值