标签:源码 补码 反码 数组定义 初始化 使用 逆置 随机数 找最大数 冒泡排序
源码 补码 反码
数组定义,初始化,使用,随机数
找最大数,逆置,冒泡排序,
scanf 输入字符串
字符串处理
字符串溢出等问题
scanf()
gets()
puts()
fputs()
strlen()
strcat()
strncat()
strcmp()
strncmp()
strchr()
strstr()
strtok()
atoi()
atof()
atol()
C 字符串数组
定义数组
遍历输出数组每个元素的值
//GCC 编译方式: C:\MinGW\project>gcc -std=c99 main.c //编码环境 GBK #include <stdio.h> int main(){ int array[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}; //遍历二维数组,并打印 for(int i=0;i< 3;i++){ for(int j=0;j<4;j++){ printf("array[%d][%d]=%d\n",i,j,array[i][j]); } } /* 输出 : array[0][0]=0 array[0][1]=1 array[0][2]=2 array[0][3]=3 array[1][0]=4 array[1][1]=5 array[1][2]=6 array[1][3]=7 array[2][0]=8 array[2][1]=9 array[2][2]=10 array[2][3]=11 */ }
字符数组多种初始化方式
研究\0 对字符串数组的影响
#include <stdio.h> int main(){ //字符串的初始化 //char str[100] ; //定义一个字符串 //char str[100] = {‘h‘,‘e‘,‘l‘,‘l‘,‘o‘}; //定义一个字符串,并初始化 char str[100] = "hello"; //多种初始化 str[0] = ‘H‘; str[1] = ‘e‘; str[2] = ‘\0‘; //遇到\0,字符串就结束了 str[3] = ‘l‘; str[4] = ‘o‘; printf("%s\n",str); //字符串就是以\0结尾的数组 //输出 He printf("str =%d\n",sizeof(str)); //输出 str =100 }
看看字符串数组\0后面是什么东西
#include <stdio.h> int main(){ //固定字符数组大小,研究字符串初始化后是什么东西 char str[10] = "Hello"; printf("str =%d\n",sizeof(str)); //输出 str2 =10 printf("str[4] char=>%c HEX=>%x\n",str[4],str[4]); printf("str[5] char=>%c HEX=>%x\n",str[5],str[5]); printf("str[6] char=>%c HEX=>%x\n",str[6],str[6]); printf("str[7] char=>%c HEX=>%x\n",str[7],str[7]); //输出: // str[4] char=>o HEX=>6f // str[5] char=> HEX=>0 // str[6] char=> HEX=>0 // str[7] char=> HEX=>0 }
显示字符串长度大小
#include <stdio.h> int main(){ //打印字符数组大小 char str1[] = "Hello"; printf("str1 =%d\n",sizeof(str1)); // 输出 str1 =6 }
修改字符串的内容
#include <stdio.h> int main(){ //修改字符串内容 char str3[99]="Hello World!"; printf("%s",str3); printf(str3); str3[4]=‘A‘; printf(str3); //输出 Hello World!Hello World!HellA World! }
逆置数组
#include <stdio.h> int main(){ char str3[99]="Hello World!"; int low=0; int high=11; //注意上面的那个字符,11位之后就是\0了 int tmp_var; while(low<high){ tmp_var =str3[low]; str3[low] =str3[high]; str3[high] =tmp_var; low++; high--; } printf(str3); //输出: //数组逆置: //!dlroW AlleH }
显示GBK编码的汉字编码
//GBK 编码 #include <stdio.h> int main(){ char str4[100] ="你好 世界"; printf("\n%s\n",str4); for(int i=0;i<13;i++){ printf("%x\n",str4[i]); } } /* C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe 你好 世界 ffffffc4 ffffffe3 ffffffba ffffffc3 20 ffffffca ffffffc0 ffffffbd ffffffe7 0 0 0 0 */
显示GBK编码的汉字
//GBK 编码 #include <stdio.h> int main(){ //用GBK编码显示 汉字 char str5[100]; str5[0]=0xc4; str5[1]=0xe3; str5[2]=0; printf(str5); //输出 你 }
scanf函数漏洞演示:
遇到空格一定会对scanf有影响
#include <stdio.h> int main(){ char a[3]={0}; char b[3]={0}; scanf("%s",a); scanf("%s",b); printf("==========\n"); printf("%s\n",a); printf("%s\n",b); } 测试: C:\MinGW\project>gcc -std=c99 str.c 正常输入: C:\MinGW\project>a.exe 12 qw ========== 12 qw
溢出测试1
C:\MinGW\project>a.exe 12 qwqwqwwqwqw ========== wqwwqwqw qwqwqwwqwqw 溢出测试2 C:\MinGW\project>a.exe 123 qwerty ========== rty qwerty
scanf 溢出的原因:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char a[10]={0}; char b[300]={0}; int c[10]; printf("a address %p\n",a); printf("b address %p\n",b); printf("c address %p\n",c); system("pause"); //程序等待在这里 } /* C:\MinGW\project>gcc str.c C:\MinGW\project>a.exe a address 0028FF16 b address 0028FDEA c address 0028FDC0 请按任意键继续. . . */
scanf会把接受到的值,在内存从开始存,不会去管是否已经溢出
这样会导致覆盖其他变量的数值
可以看出,程序已经出错
gets可以解决scanf的无法记录空格的问题 #include <stdio.h> int main(){ char a[30]={0}; gets(a); printf(a); } C:\MinGW\project>a.exe hello world ! hello world !
但是依然会缓冲区溢出
#include <stdio.h> int main(){ char a[3]={0}; char b[3]={0}; gets(a); gets(b); printf("%s\n",a); printf("%s\n",b); } C:\MinGW\project>a.exe 123456789 qwertyuioop rtyuioop qwertyuioop C:\MinGW\project>
fgets解决了空格 缓存区溢出问题
#include <stdio.h> int main(){ char a[5]={0}; // fgets(a,5,stdin); fgets(a,sizeof(a),stdin); printf("%s\n",a); } C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe 12 e343 423 12 e
puts会在输出后面加入一个\n
#include <stdio.h> int main(){ char a[]="Hello world !"; puts(a); printf("=================="); printf(a); printf("=================="); } C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe Hello world ! ==================Hello world !==================
fput函数,可以代替printf
#include <stdio.h> int main(){ char a[]="Hello world !"; fputs(a,stdout); } C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe Hello world !
对输入的字符,逆置
#include <stdio.h> int main(){ char a[99]={0}; scanf("%s",a); printf("%s \n",a); //strlen 返回是数组有效长度,不包含\0 //获取字符串真实长度,相当于strlen int i = 0; while(a[i] != ‘\0‘) i++; //逆置字符数组 int low = 0; int high= i-1; //因为字符数组有一个‘\0‘ char tmp; while(low < high){ tmp = a[low]; a[low] = a[high]; a[high]= tmp; low++; high--; } printf("%s \n",a); } C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe qwertyuio09876 qwertyuio09876 67890oiuytrewq C:\MinGW\project>a.exe 你好 你好 strlen 4 sizeof 99 煤隳
字符串追加:
注意:可能导致溢出
#include <stdio.h> #include <string.h> int main(){ char a[99]={0}; char b[300]={0}; scanf("%s",a); scanf("%s",b); strcat(a,b); //把b追加到a后面,a要足够大 printf("a+b=%s\n",a); } C:\MinGW\project>a.exe 123 abc a+b=123abc
手动实现strcat
#include <stdio.h> #include <string.h> int main(){ char a[99]={0}; char b[300]={0}; scanf("%s",a); scanf("%s",b); //strcat(a,b); //把b追加到a后面,a要足够大 //手写一个strcat int lena = strlen(a); int lenb = strlen(b); for(int i = lena;i < lena + lenb;i++){ a[i] = b[i-lenb]; } printf("a+b=%s\n",a); } C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe 123 abc a+b=123abc
strncat指定追加个数
#include <stdio.h> #include <string.h> int main(){ char a[10]={0}; char b[300]={0}; scanf("%s",a); scanf("%s",b); strncat(a,b,sizeof(a)-strlen(b)-1); //留一个‘\0‘ printf("a+b=%s\n",a); } /* C:\MinGW\project>gcc -std=c99 str.c C:\MinGW\project>a.exe 12345 qwertyuiop a+b=12345qwertyuiop */
将最高位做为符号位(0代表正,1代表负),其余各位代表数值本身的绝对值
+7的原码是00000111 -7的原码是10000111 +0的原码是00000000 -0的原码是10000000
|
一个数如果值为正,那么反码和原码相同
一个数如果为负,那么符号位为1,其他各位与原码相反
+7的反码00000111 -7的反码11111000 -0的反码11111111 |
原码和反码都不利于计算机的运算,如:原码表示的7和-7相加,还需要判断符号位。
正数:原码,反码补码都相同
负数:最高位为1,其余各位原码取反,最后对整个数 + 1
-7的补码:= 10000111(原码) 111111000(反码) 11111001(补码) +0的补码为00000000 -0的补码也是00000000 |
补码符号位不动,其他位求反,最后整个数+ 1,得到原码
用补码进行运算,减法可以通过加法实现 |
7-6=1 7的补码和-6的补码相加:00000111 + 11111010 = 100000001 进位舍弃后,剩下的00000001就是1的补码 |
-7+6 = -1 -7的补码和6的补码相加:11111001 + 00000110 = 11111111 11111111是-1的补码 |
内存连续,并且是同一种数据类型的变量,C语言的数组小标好是从0开始的,到n-1.
类型变量名称[数组元素的个数];
在内存当中是连续的内存空间地址。
int array[10] = {0};//将数组所有元素都初始化为0
int array[10] = {0,1,2,3,4,5,6,7,8,9}
数组中找最大值思路
数组中找第二大值思路
逆置数组思路
测量楼宇高度的说明
测量地球太阳距离的说明
测量太阳木星距离的说明
intarray[3][4];//12个元素的二维数组
int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; |
char buf[100];
对于C语言字符串其实就是一个最后一个元素为’\0’的char数组.
char buf[] = “hello world”;
头文件stdlib.h
#include<time.h> int t = (int)time(NULL); srand(t); for (int i = 0; i < 10; i++) { printf("%d\n", rand()); } |
char buf[100] = {0};
scanf(“%s”, buf);
scanf("请输入i的值%d",&i);
gets没有解决缓冲区溢出的问题.
gets函数不检查预留缓冲区是否能够容纳用户实际输入的数据。多出来的字符会导致内存溢出,fgets函数改进了这个问题。
由于fgets函数是为读取文件设计的,所以读取键盘时没有gets那么方便
char s[100] = { 0 }; fgets(s, sizeof(s), stdin); |
puts函数打印字符串,与printf不同,puts会在最后自动添加一个’\n’
char s[] = "hello world"; puts(s); |
fputs是puts的文件操作版本,
char s[] = "hello world"; fputs(s, stdout); |
strlen返回字符串的长度,但是不包含字符串结尾的’\0’
char buf[10]
sizeof(buf);//返回的是数组buf一共占据了多少字节的内存空间.
char str1[100];
char str2[100];
strcat(str1, str2);//把str2追加到str1的后面
str1一定要有足够的空间来放str2,不然会内存溢出.
strncat(str1, str2, sizeof(str1) –strlen(str1) - 1);
strcmp(a, “str”);//如果两个参数所指的字符串内容相同,函数返回0
strncmp(str, “exit”, 4);
strcpy(str, “hello world”);//存在溢出的问题,
strcpy(str, “hello world”, 7);
printf是向屏幕输出一个字符串
sprintf是向char数组输出一个字符串,其他行为和printf一模一样
sprintf也存在缓冲区溢出的问题
strchr(str, ‘c’);
返回值是字符’c’在字符串str中的位置
字符在第一次调用时strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL每次调用成功则返回指向被分割出片段的指针
char buf[] = "abc@defg@igk"; char *p = strtok(buf, "@");; while (p) { printf("%s\n", p); p = strtok(NULL, "@"); } |
作业说明:
不可以用任何已有的函数,完全自己写代码,完成十进制字符串转化为十进制的整数
作业思路:
本文出自 “魂斗罗” 博客,请务必保留此出处http://990487026.blog.51cto.com/10133282/1769432
标签:源码 补码 反码 数组定义 初始化 使用 逆置 随机数 找最大数 冒泡排序
原文地址:http://990487026.blog.51cto.com/10133282/1769432