A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 八寒地狱 中级黑马   /  2014-10-24 00:01  /  789 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


指针 运算

两个指针之间的减法运算

前提:

两个指针必须指向同一个数组

注意:

指针之间是没有加法运算的
两个指针相加的话,可能会越界

如果p1-p 为正 p<p1   p1在高地址
负 p>p1   p在高地质
0  p==p1  p和p1都指向同一个地

指针和二维数组

使用数组名访问数组的元素

a[0]   行地址
a[1]   行地址

*(a+0) 第0行地址 等价与a[0]
*(a+1)


a[0]+0 列地址     a[0][0]地址
a[0]+1             a[0][1]


*(a[0]+1)    取值  a[0][1]的值
*(*(a+0)+1)   a[0][1]的值
*(*(a+i)+j)   a[i][j]的值


1)指向二维数组元素的指针(数组指针)

int *p = a;  (不对)

2)二维的指针数组

int main()
{
   
    int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
    int *p = a;//不可取
   
    定义一个行指针,[4]表示这一行有四个元素
    int (*p)[4];//二维数组的行指针
    表示把二维数组名赋值给指针变量p
    p = a;
   
    a[0]    1,2,3,4
    a[1]    5,6,7,8
    a[2]    9,10,11,12
   
    a数组名
        *(a+0)   //a[0]存放地址
        *(a+1)
        *(a+2)
   
    for (int i=0; i<3; i++) {
        
        for (int j=0; j<4; j++) {
            
            //a[i]  每一个行的地址
            //a[i]+j a[i][j]的地址
            //*(a[i]+j)  a[i][j]的元素的值
            //在一维数组中 a[i]值,*(a+i)
            //printf("%d ",*(a[i]+j));
            //printf("%d ",*(*(a+i)+j));
            printf("%d ",*(*(p+i)+j));
            
        }
        printf("\n");
    }
   
    return 0;
   
}

小练习
编写函数实现将一个数组中的内容拷贝到另外一个数组中。
include <stdio.h>
void string_copy(char a[],char b[],int len){
   
    //定义两个数组指针
    char *p = a;
    char *p1 = b;
   
    for (int i=0; i<len; i++) {
        //a[i]    b[i]
        *(p+i) = *(p1+i);
    }
   
   
   
}
int main()
{
   
    char ch[6]="aaaaa";
    char ch1[6]="bbbbb";
    string_copy(ch, ch1, 6);
    printf("%s\n",ch);
   
   
    return 0;
}

三 字符串指针
*
字符串存储方式:

1)使用字符数组

char c1[]="adsfasdfas";

c1是数组的首地址,常量
c1 = "asdfasdfasdf";(错误的)

2)字符串指针

格式:char *指针变量名

1)字符串指针跟字符指针的区别
赋值区别
char c='a';
char *s=&c;    //字符指针

char *s1="dafasdfdsa";  //字符串指针

2)字符数组和字符串指针的区别

1)字符数组存放在 内存的栈 区
2) 字符串指针指向的字符串存储在 内存常量区

char *str="asdfsdfas";  //str指针变量,把字符串的首地址存放到str中

char *str2;  //指针变量
str2 = "adsfasdfasdf";


定义char类型的数组
存放到内存的栈区,可以读也可以写
char c[10]="itcast!";
c[5]='A';

str存放的是常量字符串的首地址
str可以重新指向一个新的字符串,但是字符串的内容不能改
char *str="itcast!";
printf("%s\n",str);

四 字符串数组
har ch[]="I need AV";
char ch1[]="I need AV";

字符串数组

1)二维的字符数组存储
char arr[3][20]={"dafasdf","I need AV","I need AV"};

for(int i=0;i<3;i++){
    printf("%s\n",arr[i]);
}

存在栈区:arr[0]  arr[1]   arr[2]    //可读可写

2)char型的一维指针数组
//数组中每一个元素都是指针
char *name[5]={"china","usa","hanguo","chaoxian","I need AV"}
for(int i=0;i<5;i++){
    printf("%s",name[i]);
}

name[0]  name[1]    //常量区,不能改

字符串指针练习

输入5个国名并按字母顺序排列后输出。
char
*name[]={ "CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};

include <stdio.h>
#include <string.h>

void sort_string(char *name[],int len){
   
    定义变量
    int min;
   
    循环,控制趟数
    for (int i=0; i<len-1; i++) {
        
        min = i;  //假设一个最小值
        for (int j=i+1; j<len; j++) {
            
            //比较大小
            if(strcmp(name[j], name[min])<0){
                min = j;
            }
            
        }
        
        //交换
        if (i!=min) {
            //交换的时在name数组中的顺序,原来指向谁,还指向谁
            char *temp;
            temp = name[i];
            name[i] = name[min];
            name[min] = temp;
        }
        
    }
   
   
}


int main()
{
   
    char *name[]={ "CHINA","AMERICA","HANGUO","FRANCE","GERMAN"};
    sort_string(name, 5);
    for (int i=0; i<5; i++) {
        printf("%s\n",name[i]);
    }
    return 0;
}


五 安全输入和输出函数
1)为什么说scanf和gets是不安全的

char ch[10];

//从键盘接收一个字符串
scanf("%s",ch);    //如果输入的字符串有空格,scanf就认为输入结束了,空格之后的字符都不会被报存
gets(ch);          //可以接收用户输入的字符中含有空格
//scanf和gets都有一个缺点:
用户输入多少东西,就帮你保存多少东西
aaaaaaaaaABBBBB
假设用户输入的长度>10       15   = 10存数组     5连续存了(不安全的)

puts()   //输出到缓冲区


2)fgets()   fputs()   //安全的函数

char ch1[10];
9个字符+'\0'  安全的

fgets函数主要功能是从文件中读取数据到字符数组

格式:fgets(数组名,长度,stdin);    stdin 表示标准的输入,从输入缓冲区获取数据

注意:
1)fgets() 读取'\n' 换行符      fgets获取的字符长度小与数组长度的时候,能看到
2)                           如果输入的长度大于数组长度,会自动截断
3) if (ch[strlen(ch)-1]=='\n') ch[strlen(ch)-1]='\0';


fputs()//可以写入字符串到文件中
格式:fputs(数组名,stdout);    //stdout表示输出到控制台

注意:fputs不能换行,puts可以自动换行

nt main(=)
{
    char  ch[5];
    //长度
    fgets(ch, sizeof(ch), stdin); //获取用户输入的内容,保存到ch中'
    printf("%ld\n",strlen(ch));
    if (ch[strlen(ch)-1]=='\n') ch[strlen(ch)-1]='\0';
    //输出
    //puts(ch);
    fputs(ch, stdout);  //输出到控制台
   
   
    return 0;

}
六 const 函数
如何使用const

1)声明一个常量


*/

#include <stdio.h>

int main(int argc, const char * argv[])
{
    1、修饰变量,可以让变量变成只读的(常量)
    const int a = 10;
    a = 10;
        int *p;
        p = (int *)&a;
        *p = 5;
   
        printf("%p\n",&a);
        printf("%p\n",p);
   
        printf("%d\n",a);
        printf("%d\n",*p);
   
    2、const修饰指针
   
    int b=10,c=12;
   
    1)const的作用是指针的指向可以改变,指针指向的变量的值不能改
        const int *p=&b;
        int const *p=&b;
        p = &c;
        *p = 10;
   
    2)const的作用是,指针的指向不能改变,指针的指向的变量的值可以改变
        int * const p1 = &b;
        p1 = &c;
        *p1 = 30;
   
    3)此处的const表示,指针的指向和指向变量的值都不能改变
        const int * const p2 = &b;  //可以这样写
        p2 = &c;
        *p2 = 40;
   
   
     
     技巧:
     看const在*附近的位置
     
     const 在*的左侧  值不能改变
     const 在*的右侧  指向不能改变
     const 在*的两侧  指向和值都不能改变
     
     
     
   
    return 0;
}

1 个回复

倒序浏览
我都没学到这还没开始
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马