精华内容
下载资源
问答
  • C++ 字符串 对象 C++ 字符串 对象 创建方法 C++ 字符串 对象 输出到控制台 C++ 字符串 拼接 C++ 字符串 方法调用 ( 栈内存对象 ) C++ 字符串 方法调用 ( 堆内存对象 ) C / C++ 字符串 完整代码示例



    C++ 字符串 对象


    C++ 字符串 :

    • 1.string 类 : C++ 中的字符串是 string 类 对象 ;
    • 2.string 类定义位置 : 该 string 类定义在 iostream 头文件中 , 不必引入另外的头文件 ;
    #include <iostream>
    



    C++ 字符串 对象 创建方法


    C++ 字符串 对象 创建方法 :

    • 1.直接赋值 : 直接使用 C 字符串赋值 ;
    	//① 使用字符串赋值
    	string string_c_plus_1 = " Hello ";
    
    • 2.构造方法 : 调用 string 构造方法 创建 string 对象 ;
      • ① 传入 string 参数 : string 构造方法可以传入 string 对象 ;
      • ② 传入 C 字符串参数 : string 构造方法也可以传入 一个 C 字符串 ;
    	//② 调用构造方法 初始化字符串
    	string string_c_plus_2(string_c_plus_1);
    	string string_c_plus_3(" World ");
    
    • 3.使用 new 分配内存 : 使用 new 为 String 对象分配一块堆内存空间 , 返回 string * 类型的指针 ;
    	//③ 使用 new 申请的内存 , 需要使用 delete 释放
    	string *string_c_plus_4 = new string(" New ");
    	delete string_c_plus_4;
    

    调用该 string* 对象的方法需要使用 -> 进行调用 ;

    堆内存使用原则 :
    ① 使用 new 申请的内存 , 需要使用 delete 释放 ;
    ② 使用 new [] 申请的数组 , 需要使用 delete[] 释放 ;
    ③ 使用 malloc 申请的内存 , 需要使用 free 释放 ;




    C++ 字符串 对象 输出到控制台


    C++ 字符串 对象 输出到控制台 :

    • 1.不能直接使用 cout 输出 : 下面的用法是错误的 ; 使用 cout 不能直接将 string 对象输出 ;
    	//这种用法是错误的
    	string string_c_plus_1 = " Hello ";
    	cout << string_c_plus_1 << endl;
    
    • 2.输出方法 : 需要将 string 对象转成 C 字符串 , 然后再输出 :
    	//调用 string 对象的 c_str() 方法 , 获取其 C 字符串 , 然后再输出到控制台
    	string string_c_plus_1 = " Hello ";
    	cout << string_c_plus_2.c_str() << endl;
    

    在 Java 中输出 String 对象 , 默认会调用其 toString 方法 , 但是在 C 中不可以直接使用 ;




    C++ 字符串 拼接


    C++ 字符串拼接 :

    • 1.使用 “+” 符号拼接 : 这里的加号进行了操作符重载 , 字符串之间相加代表了字符串的拼接操作 ;
    	//① "+" : 操作符重载 , 重新定义了 加号运算符的行为 , 
    	//		这里加号可以实现字符串拼接 , 与 Java 类似
    	string string_c_plus_5 = string_c_plus_1 + string_c_plus_3;
    
    • 2.调用 string 对象的 append 方法 : 调用 string 对象的 append() 方法 , 传入要拼接的字符串 ;
    	//② 调用 string 对象的 append 方法 , 拼接字符串
    	string string_c_plus_6 = string_c_plus_1.append( string_c_plus_3 );
    
    • 3.代码示例 :
    	//C++ 字符串拼接
    	//① "+" : 操作符重载 , 重新定义了 加号运算符的行为 , 这里加号可以实现字符串拼接 , 与 Java 类似
    	//② 调用 string 对象的 append 方法 , 拼接字符串
    	string string_c_plus_5 = string_c_plus_1 + string_c_plus_3;
    	string string_c_plus_6 = string_c_plus_1.append( string_c_plus_3 );
    
    • 4.运行结果 :
     Hello  World
     Hello  World
    

    在这里插入图片描述

    操作符重载 : 重新定义了操作符的作用 , 这里的 “+” 就是重新定义了其作用 , 拼接字符串 ;




    C++ 字符串 方法调用 ( 栈内存对象 )


    C++ 字符串 方法调用 : 该字符串 ( string ) 对象 在栈内存中 ;

    • 1.获取字符串长度 : 调用 string 对象的 size() 方法 , 即可返回字符串长度 ;
    	//① 使用字符串赋值
    	string string_c_plus_1 = " Hello ";
    	//获取 C++ 字符串长度 : 调用 string 对象的 size() 方法 , 获取字符串长度
    	int string_c_plus_1_size = string_c_plus_1.size();
    
    • 2.判断字符串是否为空 : 调用 string 对象的 empty() 方法 , 判断字符串是否为空 ;
    	//① 使用字符串赋值
    	string string_c_plus_1 = " Hello ";
    	//判断 C++ 字符串是否为空 : 调用 string 对象的 empty() 方法 ; 
    	bool string_c_plus_1_empty = string_c_plus_1.empty();
    
    • 3.代码示例 :
    	//使用字符串赋值
    	string string_c_plus_1 = " Hello ";
    	
    	//获取 C++ 字符串长度 : 调用 string 对象的 size() 方法 , 获取字符串长度
    	int string_c_plus_1_size = string_c_plus_1.size();
    	cout << "string_c_plus_1_size : " << string_c_plus_1_size << endl;
    
    	//判断 C++ 字符串是否为空 : 调用 string 对象的 empty() 方法 ; 
    	bool string_c_plus_1_empty = string_c_plus_1.empty();
    	cout << "string_c_plus_1_empty : " << string_c_plus_1_empty << endl;
    
    • 4.运行结果 :
    string_c_plus_1_size : 14
    string_c_plus_1_empty : 0
    

    在这里插入图片描述

    使用 “.” 方式调用栈内存对象的方法 ;




    C++ 字符串 方法调用 ( 堆内存对象 )


    C++ 字符串 堆内存对象 方法调用 :

    • 1.堆内存对象创建 : 使用 new 创建的 string 对象 需要在堆内存中为其分配内存 , 返回的是 string* 指针类型 ;
    	//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
    	// -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
    
    	string* string_c_plus_7 = new string(" New String ");
    
    • 1.获取字符串长度 : 调用 string 对象的 size() 方法 , 即可返回字符串长度 ; 需要使用 -> 代替 . 操作 ;
    	//① 获取字符串长度 : 
    	int string_c_plus_7_size = string_c_plus_7->size();
    
    • 2.判断字符串是否为空 : 调用 string 对象的 empty() 方法 , 判断字符串是否为空 ; 需要使用 -> 代替 . 操作 ;
    	//② 判断字符串是否为空 : 
    	bool string_c_plus_7_empty = string_c_plus_7->empty();
    
    • 3.使用指针的好处 :
      • ① 扩大作用域 : 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ;
      • ② 方便参数传递 : 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 ;
    • 4.代码示例 :
    	//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
    	// -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
    
    	string* string_c_plus_7 = new string(" New String ");
    	
    	//① 获取字符串长度 : 
    	int string_c_plus_7_size = string_c_plus_7->size();
    	cout << "string_c_plus_7 : " << string_c_plus_7_size << endl;
    
    	//② 判断字符串是否为空 : 
    	bool string_c_plus_7_empty = string_c_plus_7->empty();
    	cout << "string_c_plus_7_empty : " << string_c_plus_7_empty << endl;
    
    	//释放堆内存
    	delete string_c_plus_7;
    
    	//使用指针的好处 : 
    	// ① 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ; 
    	// ② 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 
    	//	  其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 
    
    • 5.运行结果 :
    string_c_plus_7 : 12
    string_c_plus_7_empty : 0
    

    在这里插入图片描述




    C / C++ 字符串 完整代码示例


    // 001_CMake_1.cpp: 定义应用程序的入口点。
    //
    
    #include "001_CMake_1.h"
    #include "c_extern.h"
    
    using namespace std;
    
    //定义方法接收 int& 引用类型变量
    //并在方法中修改该变量的值
    void quote(int& b) {
    	b = 888;
    }
    
    int main()
    {
    	cout << "Hello CMake。" << endl;
    
    	//1. C C++ 兼容
    	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/98840708
    	//调用 c_extern.h 头文件中定义的方法
    	//该方法定义在了 C 语言文件中
    	add(1, 2);
    
    
    	//2. 引用数据类型
    	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/99239635
    	//代码 展示 流程 : 
    	//① 定义 普通 类型 变量
    	int a = 8;
    	//② 定义 引用类型变量, 格式 : 类型名称& 变量名 = 对应类型变量名称 ;
    	int& b = a;
    	//③ 调用函数传入引用类型参数 : 将引用类型传给接收引用类型的方法
    	quote(b);
    	//④ 打印引用数据类型的修改结果 , 结果是 b 被修改成了 888
    	cout << b << endl;
    
    	//引用数据类型定义与使用 : 
    	// ① 引用数据类型定义 : 类型名称& 变量名 = 对应类型变量名称 ;
    	// ② 引用数据类型的使用方法 : 直接当做原来的变量使用即可, 可以替换原来变量的位置使用
    
    	//引用类型解析 : 
    	// ① int& 是引用数据类型 , b 是 a 的引用 
    	// ② 分配一块内存存放 int 类型数据 8 , 将该内存赋予一个别名 a
    	// ③ 同时又给该内存赋予另外一个别名 b 
    
    
    	//3. 字符串使用
    	//C 字符串 表示方法 : 
    	// ① 字符数组 : 本质是 字符 数组 char[] , 这里注意字符数组要以 NULL 或 '\0' 结尾; 
    	char string_c[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
    	// ② 指针 : 使用指针形式表示字符串 , 默认末尾增加 '\0' ;
    	char* string_c_p = "hello";
    
    	//字符串打印 : 
    	// ① 打印字符串 , cout 后的 << 后可以打印 字符串 , 也可以打印变量
    	// ② 输出 cout << 字符串或变量1 << 字符串或变量2 ... << endl 可以拼接 输出信息
    	cout << "string_c : " << string_c << endl;
    	cout << "string_c_p : " << string_c_p << endl;
    
    	//C 语言中的字符串操作
    	//拷贝字符串 
    	char string_c_copy_destination[6];
    	char string_c_copy_source[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
    	// ① 参数 : strcpy 方法是拷贝字符串的方法 , 第一个参数是目标字符串 , 第二个参数是源字符串
    	// ② 作用 : 该方法是将 源字符串 拷贝到 目标字符串中
    	strcpy(string_c_copy_destination, string_c_copy_source);
    	// ③ 打印拷贝结果 : 
    	cout << "string_c_copy_destination : " << string_c_copy_destination << endl;
    
    	//拼接字符串 
    	//① 定义目标字符串 : 拼接字符串的目标字符串的大小一定要大于等于要拼接的两个字符串大小之和, 否则会报错
    	char string_c_cat_destination[30] = " cat dst ";
    	char string_c_cat_source[] = " cat src ";
    	//② 拼接字符串方法参数 : 第一个参数是目标字符串 , 第二个参数是源字符串
    	//③ 目标字符串大小 : 注意 目标字符串的 大小一定要大于 两个字符串实际大小
    	strcat(string_c_cat_destination, string_c_cat_source);
    	//④ 打印字符串拼接结果 : 
    	cout << "string_c_cat_destination : " << string_c_cat_destination << endl;
    
    
    	//获取字符串长度
    	//① 参数 : 传入要获取的字符串 , 该长度不含 '\0' 结尾标志
    	//② 作用 : 获取实际的字符串长度 , 即自动识别 '\0' 位置 , 获取其长度 , 与所占用的内存大小无关
    	char string_c_len[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
    	char string_c_len2[20] = { 'h', 'e', 'l', 'l', 'o', '\0' };
    	char * string_c_len3 = "hello";
    	
    	//① 字符数组长度 , 测量从开始到 '\0' 的长度, 不包括 '\0'
    	int len1 = strlen(string_c_len);
    	//② 指定大小的字符数组长度 , 结果不是指定的大小的值 , 获取的是实际字符串长度
    	int len2 = strlen(string_c_len2);
    	//③ 指针表示的字符串 , 其获取的大小是实际字符串大小, 不包含自动添加的 '\0' 
    	int len3 = strlen(string_c_len3);
    	//④ 打印 三个字符串大小
    	cout << "len1 : " << len1
    		<< " len2 : " << len2
    		<< " len3 : " << len3
    		<< endl;
    
    
    	//字符串比较
    	// ① 参数说明 : 参数是需要比较的两个字符串 , 第一个参数 str1 , 第二个参数 str2
    	// ② 对比规则 : str1 和 str2 两个字符串 , 从左到右 逐个对比 ASCII 码 大小 ; 
    	//		a. 如果 str1 等于 str2 , 返回 0; 
    	//		b. 如果 str1 > str2 , 返回值 大于 0 ;
    	//		c. 如果 str1 < str2 , 返回值 小于 0 ;
    
    	//定义需要比较的字符串
    	char* string_c_comp_1 = "Hello";
    	char* string_c_comp_2 = "Hello";
    	char* string_c_comp_3 = "hello";
    
    	// ① 两个字符串相等
    	int cmp_result_1_2 = strcmp(string_c_comp_1, string_c_comp_2);
    	// ② "Hello" 字符串 (H 对应 ASCII 72) 小于 "hello" 字符串 (h 对应 ASCII 104) , 返回值 小于 0
    	int cmp_result_1_3 = strcmp(string_c_comp_1, string_c_comp_3);
    	// ③ "hello" 字符串 (h 对应 ASCII 104) 大于 "Hello" 字符串 (H 对应 ASCII 72) , 返回值 大于 0
    	int cmp_result_3_1 = strcmp(string_c_comp_3, string_c_comp_1);
    
    	//输出字符串对比结果
    	cout << "cmp_result_1_2 : " << cmp_result_1_2 
    		<< " cmp_result_1_3 : " << cmp_result_1_3
    		<< " cmp_result_3_1 : " << cmp_result_3_1
    		<< endl;
    
    
    	// C++ string 类 : 该类定义在 iostream 头文件中
    	//创建 string 类型对象有三种方法 : 
    	//① 直接使用字符串赋值 
    	//② 调用构造方法赋值 
    	//③ 最后可以调用 new 为字符串分配一块内存
    
    	//① 使用字符串赋值
    	string string_c_plus_1 = " Hello ";
    
    	//② 调用构造方法 初始化字符串
    	string string_c_plus_2(string_c_plus_1);
    	string string_c_plus_3(" World ");
    
    	//上面的三种字符串不需要释放 , 因为其定义在栈内存中 , 下面使用 new 创建字符串的情况需要 delete 释放内存 ; 
    
    	//③ 使用 new 申请的内存 , 需要使用 delete 释放
    	string *string_c_plus_4 = new string(" New ");
    	delete string_c_plus_4;
    
    	//使用 new [] 申请的数组 , 需要使用 delete[] 释放
    	//使用 malloc 申请的内存 , 需要使用 free 释放
    
    	//C++ 字符串输出
    	//字符串对象不能直接在 cout 中输出, cout << string string_c_plus_5 << endl; 是错误的
    	//cout << string_c_plus_2 << endl;
    	//要将 string 对象打印到控制台上, 需要将其转为 C 字符串 , char* 或 char[] 才能输出
    	cout << string_c_plus_1.c_str() << endl;
    
    
    	//C++ 字符串拼接
    	//① "+" : 操作符重载 , 重新定义了 加号运算符的行为 , 这里加号可以实现字符串拼接 , 与 Java 类似
    	//② 调用 string 对象的 append 方法 , 拼接字符串
    	string string_c_plus_5 = string_c_plus_1 + string_c_plus_3;
    	string string_c_plus_6 = string_c_plus_1.append( string_c_plus_3 );
    
    	//输出拼接的字符串
    	cout << string_c_plus_5.c_str() << endl;
    	cout << string_c_plus_6.c_str() << endl;
    	
    
    
    	//获取 C++ 字符串长度 : 调用 string 对象的 size() 方法 , 获取字符串长度
    	int string_c_plus_1_size = string_c_plus_1.size();
    	cout << "string_c_plus_1_size : " << string_c_plus_1_size << endl;
    
    	//判断 C++ 字符串是否为空 : 调用 string 对象的 empty() 方法 ; 
    	bool string_c_plus_1_empty = string_c_plus_1.empty();
    	cout << "string_c_plus_1_empty : " << string_c_plus_1_empty << endl;
    
    	//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
    	// -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量
    
    	string* string_c_plus_7 = new string(" New String ");
    	
    	//① 获取字符串长度 : 
    	int string_c_plus_7_size = string_c_plus_7->size();
    	cout << "string_c_plus_7 : " << string_c_plus_7_size << endl;
    
    	//② 判断字符串是否为空 : 
    	bool string_c_plus_7_empty = string_c_plus_7->empty();
    	cout << "string_c_plus_7_empty : " << string_c_plus_7_empty << endl;
    
    	//释放堆内存
    	delete string_c_plus_7;
    
    	//使用指针的好处 : 
    	// ① 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ; 
    	// ② 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 
    	//	  其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 
    
    
    
    
    
    	return 0;
    }
    

    展开全文
  • c函数传递字符串

    千次阅读 2019-08-23 16:13:31
    把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组。按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构...在函数中传递一个字符串作为参数下面三...

    把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组。按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别,因此,字符数组是数组的一种。字符数组实际上是一系列字符的集合,也就是字符串(String)。

    由此可得:在函数中传递一个字符串与传递一个数组类似,可参考c函数传递数组

    一 形式参数

    在函数中传递一个字符串作为参数,以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个字符指针。

    1 形式参数是一个字符指针:

    void function(char *p)

    {...}

    2 形式参数是一个已定义大小的字符数组

    void function(char array[10])

    ...}

    3 形式参数是一个未定义大小的字符数组

    void function(char array[])

    {...}

    二 调用方式

    字符数组名是一个指向字符数组中第一个字符元素的常量指针,将字符数组名(常量指针)传递给函数

    char str[20]="hello world!"

    func(str);

    三 案列展示

    #include<stdio.h>
    
    void func(char s);
    
    int main(){
        char str[20] = "hello world!"
        func(str);
        return;
    }
    
    void func(char s[]){
        printf("%s", s)
        return;
    }

     

     

     

     

    展开全文
  • 字符串和数组作为参数传递

    万次阅读 2018-04-10 17:23:49
    链接:...1. 类1: public class ArrayTest { //都是引用传递,输出的结果是"goodbbb" public void arrayPassTest(String s, String[] ss) { ...

    链接:https://www.zhihu.com/question/31203609/answer/50992895
    1.

    类1:

    public class ArrayTest   {  
        //都是引用传递,输出的结果是"goodbbb"  
        public void arrayPassTest(String s, String[] ss)  
        {  
            s = "bad";  
            ss[0] = "bbb";  
        }  
    }

    类二:

    public static void main(String[] args)   {  
            String s1 = new String("good");  
            String[] ss1 = {"aaa"}; //string数组,只有一个元素  
            ArrayTest test = new ArrayTest();  
            test.arrayPassTest(s1, ss1);    //数组传递的是引用
            System.out.println(s1+ss1[0]); 
    }

    输出:
    goodbbb

    如果你认为arrayPassTest 函数中,s是作为值传递,而ss是作为引用传递,所以有这样的输出结果,也不算错误,但是决对没有真正理解里面的原因。在这里,String 类型的传递是引用传递,也即是地址传递。这个是毋庸置疑的。因为在java里,String是对象类型,作为参数肯定是引用传递。之所以有值传递的效果,是因为Stirng内部实现时,是用char[] 来存储字符串的,所以String相当于char[]的包装类,那java中,包装类的一个特质就是值操作时体现对应的基本类型的特质。

    1.当写一个函数传递数组时,不要直接对内部成员赋值,否则结果就不可控了, 比如下面这个函数,如果myArray被某个成员函数改变了,那么传递的这个数组也会改变。

    public void setArray(String[] newArray)  {  
            this.m_myArray = newArray;  
    }  

    2.而应该这样实现比较好

    public void setArrayNew(String[] newArray)  {  
            if(newArray == null)  
            {  
                this.m_myArray = new String[0];  
            }  
            else  
            {  
                this.m_myArray = new String[newArray.length];  
                System.arraycopy(newArray, 0, this.m_myArray, 0, newArray.length);  
            }  
       } 

    记得刚学习参数方法的时候有一个问题一直困扰着我:就是引用类
    型的参数,经过方法修改后可以保留修改,也许我描述的不是很明确,看看代码:
    public static void main(String[] args) {
    String str = “abc”;
    appendStr(str);
    System.out.println(str);
    }

    private static void appendStr(String str){
       str += "def";
    }
    

    运行结果是“abc”而不是我想要的“abcdef”,不是说String是引用类型吗,怎么会这样?我想是不是String str = “abc”; 的问题,我就换成了这样:String str = new String(“abc”); 可还是一样。
    解惑:
    首先String是一个不可变类型,也就是说从声明那一刻起内存大小是固定的不可改变的,那么str += “def”; 这行代码背后又有什么不可告人的秘密呢?既然说了String是不可变的,你还愣是给加一个“def”,没办法JVM只能再开辟一块新的内存,把“abcdef”放进去,然后把新的地址给了str(appendStr方法中的),如果你在appendStr方法中输出str的值肯定是“abcdef”,也就是说appendStr方法中根本就没有改变初始存放“abc”那块内存的值(当然它想改也改了),当这个方法返回时main方法中的str依然是那个没修改前的引用,当然还是输出“abc”了。


    首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中。更何况,要想知道Java到底是传值还是传引用,起码你要先知道传值和传引用的准确含义吧?可是如果你已经知道了这两个名字的准确含义,那么你自己就能判断Java到底是传值还是传引用。这就好像用大学的名词来解释高中的题目,对于初学者根本没有任何意义。一:搞清楚 基本类型 和 引用类型的不同之处

    int num = 10;
    String str = "hello";

    这里写图片描述

    如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为”引用”,引用指向实际对象,实际对象中保存着内容。

    二:搞清楚赋值运算符(=)的作用

    num = 20;
    str = "java";

    这里写图片描述

    对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。如上图所示,”hello” 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)三:调用方法时发生了什么?参数传递基本上就是赋值操作。第一个例子:基本类型

    void foo(int value) {
        value = 100;
    }
    foo(num); // num 没有被改变

    第二个例子:没有提供改变自身方法的引用类型

    void foo(String text) {
        text = "windows";
    }
    foo(str); // str 也没有被改变

    第三个例子:提供了改变自身方法的引用类型

    StringBuilder sb = new StringBuilder("iphone");
    void foo(StringBuilder builder) {
        builder.append("4");
    }
    foo(sb); // sb 被改变了,变成了"iphone4"。

    第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。

    StringBuilder sb = new StringBuilder("iphone");
    void foo(StringBuilder builder) {
        builder = new StringBuilder("ipad");
    }
    foo(sb); // sb 没有被改变,还是 "iphone"。

    重点理解为什么,第三个例子和第四个例子结果不同?下面是第三个例子的图解:
    这里写图片描述
    builder.append(“4”)之后
    这里写图片描述
    下面是第四个例子的图解:
    这里写图片描述
    builder = new StringBuilder(“ipad”); 之后
    这里写图片描述

    从局部变量/方法参数开始讲起:局部变量和方法参数在jvm中的储存方法是相同的,都是在栈上开辟空间来储存的,随着进入方法开辟,退出方法回收。以32位JVM为例,boolean/byte/short/char/int/float以及引用都是分配4字节空间,long/double分配8字节空间。对于每个方法来说,最多占用多少空间是一定的,这在编译时就可以计算好。我们都知道JVM内存模型中有,stack和heap的存在,但是更准确的说,是每个线程都分配一个独享的stack,所有线程共享一个heap。对于每个方法的局部变量来说,是绝对无法被其他方法,甚至其他线程的同一方法所访问到的,更遑论修改。当我们在方法中声明一个 int i = 0,或者 Object obj = null 时,仅仅涉及stack,不影响到heap,当我们 new Object() 时,会在heap中开辟一段内存并初始化Object对象。当我们将这个对象赋予obj变量时,仅仅是stack中代表obj的那4个字节变更为这个对象的地址。数组类型引用和对象:当我们声明一个数组时,如int[] arr = new int[10],因为数组也是对象,arr实际上是引用,stack上仅仅占用4字节空间,new int[10]会在heap中开辟一个数组对象,然后arr指向它。当我们声明一个二维数组时,如 int[][] arr2 = new int[2][4],arr2同样仅在stack中占用4个字节,会在内存中开辟一个长度为2的,类型为int[]的数组,然后arr2指向这个数组。这个数组内部有两个引用(大小为4字节),分别指向两个长度为4的类型为int的数组。

    这里写图片描述

    所以当我们传递一个数组引用给一个方法时,数组的元素是可以被改变的,但是无法让数组引用指向新的数组。

    你还可以这样声明:int[][] arr3 = new int[3][],这时内存情况如下图
    这里写图片描述
    你还可以这样 arr3[0] = new int [5]; arr3[1] = arr2[0];
    这里写图片描述
    关于String:原本回答中关于String的图解是简化过的,实际上String对象内部仅需要维护三个变量,char[] chars, int startIndex, int length。而chars在某些情况下是可以共用的。但是因为String被设计成为了不可变类型,所以你思考时把String对象简化考虑也是可以的。String str = new String(“hello”)
    这里写图片描述
    当然某些JVM实现会把”hello”字面量生成的String对象放到常量池中,而常量池中的对象可以实际分配在heap中,有些实现也许会分配在方法区,当然这对我们理解影响不大。

    展开全文
  • 字符串作为参数的函数

    万次阅读 2018-10-23 11:36:40
    字符串作为参数传递,实际上传递的是字符串的第一个字符的地址。这以为这字符串函数原型应将其表示字符串的形参申明为char *类型。 假设要将字符串作为参数传递给函数,则表示字符串的方式有三种: char 数组...
    • 字符串是有一系列字符组成,以空值字符结尾。
    • 将字符串作为参数来传递,实际上传递的是字符串的第一个字符的地址。字符串函数原型应将其表示字符串的形参申明为char *类型。

    假设要将字符串作为参数传递给函数,则表示字符串的方式有三种:

    1. char 数组名;
    2. 用引号的字符串常量(字符串字面值);
    3. 被设置为字符串的地址的char指针;
    char ghost[15] ="galloping";
    char * str="galumhing";
    int n1=strlen(ghost);           //参数为char数组名
    int n2=strlen(str);             //参数为字符串的指针
    int n2=strlen("gamboling");     //参数为字符串字面值
    

    处理字符串中字符的标准方式:

    while(*str)
    {
    	statement;
    	str++
    }
    
    展开全文
  • shell脚本中如何在字符串传递变量

    万次阅读 2019-08-25 19:09:10
    一种情况 字符串 本身 用单引号.一种情况 字符串 本身 用双引号举个应用场景的例子总结 摘要: 如何 在shell 脚本 中 传递解析变量的值. 分享一个shell 中的一个小技巧, 动态改变字符串中的一些值, 通过变量的方式 ...
  • 数组的传递字符串传递

    千次阅读 2018-10-30 22:23:26
    数组可以作为方法的参数和返回值,参数传递规则:传递数组引用,即指向同一个数组,如果声明...当字符串作为参数传递时,方法体中任何操作都不会改变原字符串,只会新创建一个字符串,因为字符串一旦创建就不可变。...
  • C语言字符串做函数参数

    千次阅读 2020-10-30 09:03:15
    一维字符串内存模型:两种 void copy_str01(char *from, char *to) { for (; *from!=’\0’; from++, to++) { *to = *from; } *to = ‘\0’; } void copy_str02(char *from, char *to) { while(*from!=’\
  • 有时候我们在传递数组格式的参数时到了后台接口变成了字符串格式,如: https://xx/xx/xx/x/x?idlist=['1','2'] 在后台获取到: { "code": 0, "data": { "Info": [], "idlist": "['1','2']" } } 只需要做...
  • 改文档主要叙述js点击事件传递参数参数类型,有案例有注释 字符串拼接,有案例,有各种拼接方法对比及各类数据类型的案例。
  • (转载)... 作者:燕潇洒 ...导读:微信小程序向下个页面传递各种参数,和下个页面对参数的获取。...传递字符串 //传递参数(?model中,model是下个页面获取时的key) click:function(e){ var model =
  • javascript function传递 参数参数字符串 如何拼接(有些参数是通过变量得到的) 如何拼接
  • ![图片说明](https://img-ask.csdn.net/upload/201903/02/1551509227_48285.png) 为什么,字符串数组不能直接作为参数传递,需要定义变量后变量的形式进行传递
  • 1、在传递参数的时候,首先要有正确的写法 onclick事件动态传递参数的话,则需拼接参数,如果书写错误则会报错误,在...3、还有一种传递参数形式如下 传递方式可适应后端的get、post请求而选择
  • import java.util.Scanner; class Test01{ public static void main(String[] args) { Scanner sc = new Scanner... System.out.println("请输入一个字符串:"); String str = sc.nextLine(); System.out...
  • axios get请求方式 传递给后台的参数都是字符串形式,无法传递json对象 或数组对象等  post请求方式则可以实现,  但若后台接口要求必须用get方式传递对象给后台,需要装插件,实现方法如下: 再复习下Axios ...
  • 方法的参数传递 ...方法调用时,实际参数的地址而不是参数的值被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
  • 详解 Python 字符串(一):字符串基础

    千次阅读 多人点赞 2021-01-16 20:59:45
    文章目录1.2. 在 Python 中,字符串就是一串字符的...Python 通过 str 类型提供大量方法来操作字符串,如字符串的替换、删除、截取、复制、连接、比较、查找、分隔等。本文将详细介绍操作字符串的一般方法。 1. 2. ...
  • 字符串和数字

    千次阅读 2020-10-23 09:26:16
    shell 提供了各种执行字符串操作的参数展开功能。 除了算术展开(在第七章中接触过),还有一个常见的命令行程序叫做 bc,能执行更高级别的数学运算。 参数展开 尽管参数展开在第七章中出现过,但我们并没有详尽地...
  • 1字符串传递,首先是c#与matlab之间进行参数传递用到MWArray这一参数类型作为桥梁,c#调用matlab的方法有好几种,这里我才用的是把mat文件编译成.dll文件,然后再c#中添加引用,具体步骤可参考...
  • 简述 在常规的web开发过程中,大部分上传文件都是在web页面端通过表单直接提交,再由服务器端捕获请求来...Base64字符串形式上传文件——服务器端Java/Servlet接受请求数据中的字符串内容并转换成文件
  • - 问题: 通过vue-router,实现... - elementUI的Select选择器,options选项的value值为全等比较,若原有value值类型为数字而传入的是字符串,不会做转换,故value类型需确定好,防止出现问题 - 源代码-页面A: //...
  • Java字符串(超超超详细)

    千次阅读 多人点赞 2021-03-06 08:46:59
    在程序中经常会用到字符串及对字符串的各种操作,如字符串的连接、比较、截取、查找和替换等。Java提供了Java.lang.String类来对字符串进行这一系列的操作,以及StringBuffer类 字符 字符是用单引号括
  • 第一个: 表示执行匹配的正则表达式,也可以传递字符串 第二个: 表示准备代替匹配的子字符串 var s = "index.html"; var b = s.replace("html", "htm"); replace()方法同时执行查找和替换两个操作。该方法将...
  • js模板字符串

    千次阅读 2020-02-28 23:21:43
    文章目录定义语法形式模板字符串特征(反引号,占位符,标签)字符串插值示例模板嵌套带标签的模板字符串总结 资料原文 定义 模板字面量(模板字符串): 允许在其中嵌入表达式的字符串字面量 属于字符串字面量 允许将...
  • 当我们不知道这些技巧时,我们可能会使用其他“奇技淫巧”,比如,我们很容易会忽略axios默认支持get请求传递对象的事实,然后采用手动拼接、第三方库、或手动编写函数的方式将对象转换为查询参数,拼接成最终的url...
  • c语言字符串

    万次阅读 多人点赞 2018-12-05 14:04:48
    c语言字符串都是“/0”结尾 而这里就有三个概念 EOF /0 -1 /n 首先c语言中所有字符串的结尾标志都是/0 是字符串结尾的标志 它是一种转义符 而EOF是文件流结束标志代表着 文件(file),也可以是标准输入...
  • AJAX对于JAVA接收...  在JAVA项目开发中,接口的接收参数有的是json字符串 形式接收的,后台写法如下: public ObjectMapper jsonTranster = new ObjectMapper(); @CrossOrigin @RequestMapp...
  • 版权声明:转载请注明作者(独孤尚良dugushangliang)出处: https://blog.csdn.net/dugushangliang/article/details/90370560 ...data的格式使用url参数字符串: 通过对比返回内容,我们可以看到,主要区...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    传递 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递 为什么 Java 中只有值传递传递和引用传递有什么区别 Java包 JDK 中常用的...
  • 问题:vue项目中,用axios封装请求数据时,get请求传递参数为数组时,get拼接url并不能把参数正确的传递过去, 解决:get传参需要前面自己转一下传参的格式 最初错误传参 let provinces= ['1', '2', '3'] axios.get...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 338,521
精华内容 135,408
关键字:

参数以字符串形式传递