C语言基础学习(四)

C语言 (数组 指针 函数)

数组 字符串

张三的身高 int a = 170
李四身身高 int b = 168
王五的身高 int c = 171

数组:
一次性在内存中申请连续的空间

数组的数据类型 数组变量名[ 元素的总个数 ]

100个int
int arr[100] arr 是数组变量名,简称数组名
一位数组 int a[10]; 二维数组 int[10][10]; n维数组 int([10]Xn),记住一个整数(int)站4个字节
数组的定义
数组的初始化
数组类型 数组名[ ]
int arr[5] = { 170, 168, 171, 175, 169 }; 对一个数组arr进行完整的初始化
int arr[ ] = { 170, 168, 171, 175, 169,180 }; // 系统会统计出实际该arr有6个成员
// 等价于 int arr[ ] = { 170, 168, 171, 175, 169,180 };

int arr[5] = { 170, 168 };// 只要在初始化时候对数组有一个赋值
//那么系统就会自动给后面的元素赋值为0
int arr[10] = {0};
注意 如果写成int arr[10] ; 那数组中放置的都是随机值

GNU-C支持可变长数组
int cnt;
scanf(“%d”, &cnt);
int arr[cnt];// 在程序运行到这一步时候, 这个cnt的值必须是已知的
// 这个arr就是可变长数组,不能对可变长数组进行初始化

数组的使用
数组名[元素的下标 ] 表示某个元素

如已有 int arr[5] = { 170, 168, 171, 175, 169 }; 表示数组arr有5个元素
下标的有效范围是(0 ~~ n-1)
arr[0] 是170
arr[1] 是 168
arr[4] 是169

C不会对下标进行检测,可以通过越界的下标来访问其它空间
arr[5] 这个写法是可以编译通过的,但是运行的结果是不可预计的
可能可以得到某个值,也有可能段错误

要求定义一个由10个int类型的数据构成的数值
1: 对该数组的数据进行初始化
并打印该数组的各个元素值
2: 对该数组的各个元素从键盘重新赋值
%d , &arr[i]
并打印该数组的各个元素值

GNU-C
默认 for(不能定义变量的)
int i;
for(i = 0 ; i< ; i++)

char 类型数组
要求定义一个由5个char类型的数据构成的数值
char arr[5] = { 1, 2,3,4,5};
char arr[5] = { ‘1’, ‘2’ , ‘3’ , ‘4’ , ‘5’};
等价于:char arr[5] = { 49, 50 , 51 ,52, 53};

char arr[5] = { ‘a’, ‘b’, ‘c’};
等价于:char arr[5] = {97, 98, 99, 0 , 0};
char arr[ ] = { ‘a’, ‘b’, ‘c’};
等价于:char arr[3] = { ‘a’, ‘b’, ‘c’}

char arr[ ] = “hello”; “”内一定最后是‘\0’
字符数组的初始化可以在等号的右边直接用字符串“”赋值
“hello” ===> {‘h’,’e’,’l’,’l’,’o’, ‘\0’}
{‘h’, ’e’, ’l’, ’l’, ’o’, 0}

000 0 00 NUL ‘\0’ \0就是数字0
等价于 char arr[6] = “hello”;

和字符串的差异
%s 1:scanf 把键盘的输入当成是字符连续输入,放入到对应地址中
如果遇到了空格或者是\n的时候就停止输入并自动在后面添加上’\0’
2: 打印的时候是基于对应的地址连续取内存中的值并打印对应的字符,
直到遇到了’\0’为止

“”给字符数组赋值时候,内有一个’\0’

数组名int arr[5]的一个通常两个例外(背)
1: 通常情况arr表示的是首元素的地址
2: sizeof(arr) 表示整个数组占用内存的大小
&arr 表示整个数组的地址

例子: 输入一串字符, 把里面的大写字母都变成是小写字母并输出
#include <string.h>

char str[100];
scanf(“%s”, str);

for(i=0; i<strlen(str) ; i++)
sizeof(str) ----100

字符串相关函数 string.h
strlen(char * str)
得到字符串的有效字节数, 不包括‘\0’
strlen(数组名), 可以得到该数组实际的字节

char buf[100];
scanf(“%s”, buf); // 2qn3jqke ‘\0’
希望可以通过自己写的代码来计算出整个buf中有效字符数
int i;
for(i = 0; buf[i] !=’\0’ ; i++ )
{
;// 不干活
}
// 此处i就是有效字符数

strcat(字符串1名, 字符串2名 )
合并两个字符串
char buf1[ 100 ] = “hello”; // 要保证目标字符串的大小, 保证不越界
char buf2[ 4 ] = “123”;
strcat(buf1, buf2);
buf1的内容会改变, 变成”hello123”
buf2的内容不变
strcat 在合并时候没越界检查
如果需要设置合并的字节数,则使用
strncat (字符串1名, 字符串2名, 合并字节数)

strcpy (字符串1名, 字符串2或者是字符串2名)
把字符串2的内容覆盖复制到字符串1中

strcmp(字符串1名, 字符串2或者是字符串2名)
把字符串1 和字符串2逐个字符进行比较,
只要判断到有一个字符不相同, 就停止比较并返回比较的结果
如buf1[i] > buf[i] 那返回结果>0
如buf1[i]< buf[i] 那返回结果<0
如果全部字符都相同, 返回0
比较过程中区分大小写, 小写字母比较大哦

如果只需要比较两个字符串的头n个字符
strncmp(字符串1名, 字符串2或者是字符串2名, n );

strtok (字符串1名, 字符串2或者是字符串2名)
字符串分割, 字符串2就是分割符号集合
在调用过程中,根据字符串2中的任意一个字符实现对字符串1的分割
“192.168.1.29” “.?:”
192
168
1
29
zhangsan:18 :F?170,78

参考代码:
printf(“please enter a string:\n”);
scanf("%s", buf1);
printf(“please enter a delim-string:\n”);
scanf("%s", buf2);

char *p=strtok(buf1, buf2);
int i = 1;
while(p!=NULL)//如果已经没有东西可以分割了,返回值也是NULL
{
	printf("[%d] %s \n", i++, p);
	//继续分割之前的字符串, 那么第一个参数设置成NULL, 
	p=strtok(NULL, buf2);
}
原创文章 21 获赞 6 访问量 5347

猜你喜欢

转载自blog.csdn.net/weixin_44244812/article/details/105273849