Day09

变量作用域

C语言变量作用域

1. 如果是局部变量和全局变量同名,那么在访问变量时候,采用就近原则
   会现在局部变量中寻找,找不到再去全局变量中找
2. 在函数中不能访问其他函数中定义的局部变量
3. 在函数中可以访问全局变量
4. 多个函数可以共享一个全局变量

字符串

  • 基本概念
/*
     * 1. 字符串是什么?
     * 将字符串在一起就是字符串,在C语言中字符串就是一个特殊的数组而已
     *
     * 2. 特殊点:
     *   如果想要用数组来表示字符串,那么数组必须是char类型的,而且最后一个元素
     * 必须是\0
     *
     * 3. 由于字符串比较特殊
     *   所以在C语言中除了可以用字符数组来表示字符串,还可以用""来表示字符串
     *
     */

    char str1[] = {'w', 'j', 'n', '\0'}; //字符串以'\0'结尾
    char str2[] = {'w', 'j', 'n'}; //不是字符串,是字符数组
    //赋值的同时部分初始化,没有初始化的元素会自动赋值为0
    char str3[10] = {'w', 'j', 'n', '\0'};
    chr str4 = "wjh";
    printf("%s\n", str);
  • 字符串内存分析
    //两者在内存中存储的状态
    char str1[] = {'w', 'j', 'n', '\0'}; //字符串
    char str2[] = {'w', 'j', 'n'};  //字符数组
  • 字符串输出和输入
    字符串输出: puts(str); 字符串输入: gets(ch);
   /*
     * 字符串输出和输入问题
     */


    //1. 字符串输出
    char str[] = "lnj";
    //1.1 printf("%s"),%s会从数组的第0个元素开始打印,直到遇到\0位置
    //    这种输出不会自动换行需要\n,还可以添加自定义内容
    printf("%s\n", str);

    //1.2 puts输出会自动换行,但是不能自定义添加内容
    puts(str);



    //2. 字符串输入
    char ch[10];
    //2.1 scanf("%s", &ch);接收字符串,输入的数据中不能有空格/TAB/回车,系统会将他们默认为结束字符
    //scanf("%s", &ch);
    //printf("%s\n", ch);
    //2.2 gets接收方式
    //    可以输入空格TAB符号
    gets(ch);
    printf("%s\n", ch);
  • 字符串系统函数
    注意点: 使用此类函数必须在头部导入#include <string.h>
    /*
     * 字符串长度计算 strlen();
     */

    char str[] = "niuzi";
    //注意点: 这种计算字符串长度不包括\0字符,而且还能计算出字符串中存储字符数,但是使用系统函数需要在头部导入#include <string.h>
    int len = strlen(str);
    printf("%i\n", len); // 5
#include <string.h>
int main()
{
    /*
     * 字符串拼接
     * strcat(ch1,ch2),传入两个数组,会将后面字符串数组拼接到前面
     * 注意点: 前面的数组必须足够长,能够容纳两个
     */
    char str1[10] = "niuzi";
    char str2[] = "wjh";
    strcat(str1, str2);

    printf("%s\n", str1);
    printf("%s\n", str2);
    
    return 0;
}

include <stdio.h>
#include <string.h>
void myStrncar(char dest[], char src[], int count);
int main()
{
    /*
     * 字符串拼接
     * strncat(dest, src, count);
     * 会将src中count个字符拼接到dest后面
     */

    char str1[20] = "niuzi";
    char str2[10] = "888666";
    strncat(str1, str2, 2);
    printf("%s\n", str1);
    return 0;
}
    /*
     * 字符串拷贝
     * 会将后面的字符拷贝到前面,覆盖前面原有的内容
     */

    char str1[20] = "wjh";
    char str2[20] = "haha";

    strcpy(str1, str2);
    printf("%s\n", str1);
    /*
     * 字符串比较
     * 会依次从第0个索引开始,取出第一个数组和第二个数组中每个元素
     * 如果str1当前元素大于str2当前元素,那么返回一个正数
     * 如果str1当前元素小于str2当前元素,那么返回一个负数
     * 如果str1当前元素等于str2当前元素,那么返回一个0
     *
     */


    char str1[10] = "124";
    char str2[10] = "124";

    int res = strcmp(str1, str2);
    printf("%i\n", res);

指针

  • 指针变量
    /*
     * 指针变量:
     *    指针变量和普通变量一样,都是用来保存数据的,只不过和普通变量有一点区别
     *    普通变量可以保存基本数据类型,指针变量只能保存内存地址,简言之就是保存内存地址的变量
     * 格式:
     *   数据类型  *变量名称;
     */

    int num = 7;
    int *p; //定义一个指针变量

    //注意点: 所有指针变量占用内存的大小是一样的,与指针数据变量数据类型无关
    //  在32位编译器中,占用4个字节
    //  在64位编译器中,占用8个字节
    //  只要一个变量存储了另外一个变量的内存地址,那么我们可以说这个变量指向了另外一个变量
    //  而且我们可以根据这个内存地址找到另外变量的内存地址,从而操作这部分内存


    p = &num; // 将num变量占用内存最小的地址存储到指针变量P中
    printf("%p\n", p);
    printf("%p\n", &num);
    printf("%p\n", &p); //取出p自己的地址
  • 指针内存


  • 指针变量操作数据

    /*
     * 指针变量操作存储地址数据
     */

    int num = 8;
    int *p;
    p = &num;
    //1. 只要一个变量指向了另外一个变量,就可以通过*变量名称的方法,操作另外一个变量的内存空间
    *p = 10; //在指针前面加上*号代表访问指针指向的那块内存
    printf("%i\n", num); //10
    
    
    //2. 指针只能保存地址,不能存储其他的值
    //3. 一个变量地址可以被多个指针指向
    //4. 指针的指向可以改变,后赋值的地址会覆盖前面赋值的地址
    //5. 定义指针变量时候,前面的数据类型,一定要和将来保存的变量前面的数据类型一致
    
    int num2 = 10;
    int *p1; // 正确   错误写法: double *p1;
    p1 = &num2;
  • 指针的类型
    注意: 如果函数的形参是数组或者是指针,那么就可以在函数中修改外界传入变量的值
#include <stdio.h>
void change(int *num);
int main()
{
    /*
     * 指针类型:
     *   由于指针变量指向的是某一个变量占用的存储空间的首地址
     *   所以在获取指向变量中存储数据的时候,指针是不知道要获取多少个字节的数据的
     *   所以指针变量的数据类型的作用,就是告诉指针,在获取指向变量的数据时候,需要
     *   获取几个字节的数据
     *
     * int *p 将来获取p指向的那个变量的数据的时候,需要获取4个字节的数据
     */

    int num = 10;
    change(&num); //注意参数如果是指针类型,此处应该传入地址
    printf("%i\n", num); //666
    return 0;
}
//结论: 如果函数的形参是数组或者是指针,那么就可以在函数中修改外界传入变量的值
void change(int *num){
    *num = 666;
}
  • 多级指针
    注意点: 多级指针取值格式: **p,几级指针前面就加几个*
    /*
     * 多级指针:
     *   指针中保存的是其他指针的地址
     * 
     * 如何定义多级指针
     * 在保存的指针变量的基础上加上*即可  int *p --> int **pp
     *
     * 定义指针规则:
     * 1. 将要指向的变量的定义拷贝过来
     * 2. 再将拷贝过来的代码的类型和变量名称中间加上*
     * 3. 修改变量名称
     */

    int num = 10;
    int *p; // 一级指针
    p = &num;

    int **pp; //二级指针
    pp = &p;

    // **pp -> *p ->num  三个相等
    printf("&num = %p\n", &num);  //0028FEB8
    printf("p = %p\n", p);  //0028FEB8
    printf("&p = %p\n", &p); //0028FEB4 一级指针对应本身的地址
    printf("&pp = %p\n", &pp); //0028FEB0  二级指针对应本身的地址
    printf("pp = %p\n", pp);  //0028FEB4  二级指针存储的是一级指针自身的地址
    printf("*pp = %p\n", *pp); //0028FEB8
    printf("**pp = %i\n", **pp); //10  取出num内存的值


    int ***ppp; //三级指针
    ppp = &pp;
  • 指针与数组
   /*
     * 指针和数组
     *
     * 数组名称保存的就是数组占用内存最小的那个地址
     * 既然数组名称是保存地址,指针也可以保存地址,所以指针也可以指向数组
     *
     * 结论: 如果利用指针保存数组的地址之后,那么p = ages = &ages;
     */

    int ages[3] = {1,3,5};
    printf("%i\n", ages[1]); //3

    int *p;
    p = &ages;
    p[1] = 333;
    printf("%i\n", p[1]); //333
  • 指针加减法
/*
     * 指针加减法
     * 应用场景: 一般都是用在数组中
     * 指针变量+1,加的就是指针变量类型占用的字节数
     * -1操作一般都不会用到
     *
     */
    int arr[3] = {1,3,5};
    int *p = &arr;
    printf("%i\n", *p); // 1  默认指向是数组最小的地址然后取出4个字节
    printf("%i\n", *(p+1)); //3
    printf("%i\n", *(p+2)); //5

    printf("%i\n", *p++); //1
    printf("%i\n", *p++); //3
    printf("%i\n", *p++); //5
  • 指针和字符串
 /*
     * 指针定义字符串
     * 字符串本身就是数组,所以指针也可以定义字符串
     */

//    char str1[] = "hui";
//    //char *str2 = "hui";
//    printf("%s\n", str1);
//    printf("%s\n", str2);

    /*
     * 利用数组和指针定义字符串的区别:
     * 1. 存储位置不同
     *   如果是通过数组定义的字符串,那么存储在内存当中
     *   如果是通过指针定义的字符串,那么存储在内存的常量区中
     * 2.存储空间地址不同
     *   如果是通过数组定义的字符串,每次定义都要重新开辟存储空间
     *   如果是通过指针定义的字符串,重复定义不会重新开辟存储空间
     * 3.由于在内存中存储的位置不一样,所以特性也不一样
     *   如果是通过数组定义的字符串,我们可以手动修改
     *   如果是通过指针定义的字符串,我们不能手动修改
     */

    char *str1 = "lnj";
    char *str2 = "lnj";
    str1[1] = 's'; //不能修改
    printf("%s\n", str1);
//    printf("%p\n", str1); //地址一样
//    printf("%p\n", str2);
int main()
{
    //1. 接收字符串的时候,只能通过字符数组不能通过字符指针
    //2. 学习指针之后,建议将过去传入数组类的形参修改位指针类型
    /*
     * 如果函数中返回的字符串类型是通过数组创建的,那么外界无法获取
     * 如果函数中返回的字符串类型是通过指针创建的,那么外界可以获取
     * 这是因为指针类型存储数组存在常量区当中
     */
    char *str;
    scanf("%s",str); //这种错误
    return 0;
}

void test(int *arr){ //这样方式接收数组类型参数
    
}

char* demo(){
    char *str = "wjh";
    return str;
}
  • 指针变量特点
1. 可以用来保存数据
2. 可以当做形参
3. 可以用来当做返回值
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,881评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,052评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,598评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,407评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,823评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,872评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,037评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,778评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,505评论 1 247
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,745评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,233评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,231评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,141评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,939评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,954评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,784评论 2 275

推荐阅读更多精彩内容