数组名是首元素地址,但是有2个例外,sizeof(数组名单独放在内部)和&数组名,它们两个表示整个数组,此外都是数组首元素。
123456789101112131415 | #include <stdio.h>int main() { int a[] = {1,2,3,4}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a+0)); printf("%d\n",sizeof(*a)); printf("%d\n",sizeof(a+1)); printf("%d\n",sizeof(a[1])); printf("%d\n",sizeof(&a)); printf("%d\n",sizeof(*&a)); printf("%d\n",sizeof(&a+1)); printf("%d\n",sizeof(&a[0])); printf("%d\n",sizeof(&a[0]+1)); return 0;} |
用' '单引号括起来的字符型数组,最后没有\0,例如下面的数组,只有a,b,c,d,e,f六个元素。
123456789101112 | #include <stdio.h>int main() { char arr[] = {'a','b','c','d','e','f'}; printf("%d\n",sizeof(arr)); printf("%d\n",sizeof(arr + 0)); printf("%d\n",sizeof(*arr)); printf("%d\n",sizeof(arr[1])); printf("%d\n",sizeof(&arr)); printf("%d\n",sizeof(&arr+1)); printf("%d\n",sizeof(&arr[0]+1)); return 0;} |
用' '单引号括起来的字符型数组,最后没有\0,例如下面的数组,只有a,b,c,d,e,f六个元素。
12345678910111213 | #include <stdio.h>#include <string.h>int main() { char arr[] = {'a','b','c','d','e','f'}; printf("%d\n",strlen(arr)); printf("%d\n",strlen(arr + 0)); printf("%d\n",strlen(*arr)); printf("%d\n",strlen(arr[1])); printf("%d\n",strlen(&arr)); printf("%d\n",strlen(&arr+1)); printf("%d\n",strlen(&arr[0]+1)); return 0;} |
用" "双引号括起来的字符型数组,最后还有一个\0。例如下面的数组,有a,b,c,d,e,f,\0七个元素。
123456789101112 | #include <stdio.h>int main() { char arr[] = {"abcdef"}; printf("%d\n",sizeof(arr)); printf("%d\n",sizeof(arr + 0)); printf("%d\n",sizeof(*arr)); printf("%d\n",sizeof(arr[1])); printf("%d\n",sizeof(&arr)); printf("%d\n",sizeof(&arr+1)); printf("%d\n",sizeof(&arr[0]+1)); return 0;} |
12345678910111213 | #include <stdio.h>#include <string.h>int main() { char arr[] = {"abcdef"}; printf("%d\n",strlen(arr)); printf("%d\n",strlen(arr + 0)); printf("%d\n",strlen(*arr)); printf("%d\n",strlen(arr[1])); printf("%d\n",strlen(&arr)); printf("%d\n",strlen(&arr+1)); printf("%d\n",strlen(&arr[0]+1)); return 0;} |
p里面存放常量字符串中a的地址,常量字符串里包含a,b,c,d,e,f,\0。
12345678910111213 | #include <stdio.h>#include <string.h>int main() { char *p = "abcdef"; printf("%d\n",sizeof(p)); printf("%d\n",sizeof(p + 1)); printf("%d\n",sizeof(*p)); printf("%d\n",sizeof(p[0])); printf("%d\n",sizeof(&p)); printf("%d\n",sizeof(&p+1)); printf("%d\n",sizeof(&p[0]+1)); return 0;} |
12345678910111213 | #include <stdio.h>#include <string.h>int main() { char *p = "abcdef"; printf("%d\n",strlen(p)); printf("%d\n",strlen(p + 1)); printf("%d\n",strlen(*p)); printf("%d\n",strlen(p[0])); printf("%d\n",strlen(&p)); printf("%d\n",strlen(&p+1)); printf("%d\n",strlen(&p[0]+1)); return 0;} |
二维数组的大小:
12345678910111213141516 | #include <stdio.h>int main() { int a[3][4] = {0}; printf("%d\n",sizeof(a)); printf("%d\n",sizeof(a[0][0])); printf("%d\n",sizeof(a[0])); printf("%d\n",sizeof(a[0] + 1)); printf("%d\n",sizeof(*(a[0] + 1))); printf("%d\n",sizeof(a+1)); printf("%d\n",sizeof(*(a+1))); printf("%d\n",sizeof(&a[0]+1)); printf("%d\n",sizeof(*(&a[0]+1))); printf("%d\n",sizeof(*a)); printf("%d\n",sizeof(a[3])); return 0;} |
总结:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示的是整个数组,取出的是整个数组的地址。
- 除此之外,所有的数组名都表示首元素的地址。
1234567 | #include <stdio.h>int main() { int a[5] = {1,2,3,4,5}; int *ptr = (int *)(&a + 1); printf("%d,%d\n",*(a + 1),*(ptr - 1)); return 0;} |
打印的结果是2,5
&a + 1跳过整个数组,进入下一个数组,(int *)转换成整型指针。
(ptr - 1)整型指针-1,向前挪动4字节,再解引用,也就是5.
1234567891011121314151617181920 | #include <stdio.h>struct Test{ int Num; char *pcName; short sDate; char cha[2]; short sBa[4];}* p; int main(){ printf("%p\n",p +0x1); printf("%p\n",(unsigned long)p + 0x1); printf("%p\n",(unsigned int*)p + 0x1); return 0;} |
printf("%p\n",p +0x1); p+0x1就相当于是p+1,先看p的类型,是结构体指针类型,就是跳过一个结构体,也就是0x100000+20,结果是0x100014
printf("%p\n",(unsigned long)p + 0x1); 就是整型+1,先把0x100000转换成10进制,即1048576+1,再转换成16进制,也就是0x100001。
printf("%p\n",(unsigned int*)p + 0x1);,强转成无符号整型指针,+1跳过一个无符号整型的大小,即4字节,也就是0x100004。
指针+-整数,取决于指针类型。
12345678 | #include <stdio.h>int main(){ int a[4] = {1,2,3,4}; int *ptr1 = (int *)(&a+1); int *ptr2 = (int *)((int)a+1); printf("%x%x",ptr1[-1],*ptr2);} |
ptr1是一个指针,指向a后面的一个地址。也就是4
((int)a+1)将a的地址强制转换为整数,再加1。最后(int *)再转换为地址。即0x02000000
12345678 | #include <stdio.h>int main(){ int a[3][2] = {(0,1),(2,3),(4,5)}; int *p; p = a[0]; printf("%d",p[0]);} |
nt a[3][2] = {(0,1),(2,3),(4,5)};数组内有逗号表达式,
即a[0][0] = 1,a[0][1] = 3,a[1][0] =5,后面没有初始化,默认为0
p = a[0];a[0]是第一行数组名,即a[0][0]的地址存到p中
打印的结果是1。
12345678 | #include <stdio.h>int main(){ int aa[2][5] = {1,2,3,4,5,6,7,8,9,10}; int *ptr1 = (int*)(&aa+1); int *ptr2 = (int*)(*(aa+1)); printf("%d,%d\n",*(ptr1-1),*(ptr2-1));} |
对于ptr1:
(&aa+1)相当于是跳过了这个二维数组,也就是10后面的那一个指针,是一个数组指针。
(int*) 把这个数组指针强转成了整型指针。
对于ptr2:
aa表示二维数组的第一行,+1就进入了第二行。
对它进行解引用,拿到了第二行的首元素的地址,即6
ptr2就是6的指针。
结果就是10,5
123456789 | #include <stdio.h>int main(){ char *a[] = {"work","at","alibaba"}; char**pa = a; pa++; printf("%s\n",*pa); return 0;} |
char *p = "abcdef"这种写法是把这个常量字符串的首字母a的地址放到p指针里面去。
char *a[] = {"work","at","alibaba"}; 这句的意思就是把w、a、a(首字母)的地址放到a这个char型数组里。
char**pa = a;表示把数组a的首元素地址放到pa里。
pa++也就是第二个元素的首字母地址。
打印的结果是at
12345678910 | #include <stdio.h>int main(){ unsigned long pulArray[] = {6,7,8,9,10}; unsigned long *pulPtr; pulPtr = pulArray; *(pulPtr + 3) += 3; printf("%d,%d\n",*pulPtr,*(pulPtr + 3)); return 0;} |
pulPtr = pulArray;就是把pulArray这个数组的首元素地址赋给pulPtr。
*(pulPtr + 3)就是先把pulPtr的地址+3,也就是从pulArray的首元素往后数三个元素,也就是9这个元素的地址。再解引用,也就是9。最后9+=,即12。也就是原先9这个元素的地址变成了12。
字符串逆序
写一个函数,可以逆序一个字符串的内容。
1234567891011121314151617181920212223242526 | #include <stdio.h>void Reverse(char* arr,int sz){ int left = 0; int right = sz-1; char temp = 0; for (left = 0;left<sz/2;left++) { temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; right--; }} int main(){ char arr[] = {'a','b','c','d','e','f','g','h','i','j'}; int sz = sizeof(arr)/sizeof(arr[0]); int i = 0; Reverse(arr,sz); for (i=0; i<sz; i++) { printf("%c ",arr[i]); } printf("\n");} |
计算a+aa+aaa+aaaa+aaaaa的前5项之和,a是数字
S_n=2+22+222+2222+22222,中n=5,x=2
123456789101112131415161718 | #include <stdio.h>int main(){ int x = 0; int n = 0; int sum = 0; int i = 0; int ret = 0; printf("Sn = 2 + 22+ 222 + 2222 + 22222\n"); printf("上述x = 2,n = 5\n"); printf("请输入x和n:->"); scanf("%d%d",&x,&n); for (i=0; i<n; i++) { ret = ret*10 + x; sum = sum+ ret; } printf("%d\n",sum);} |
求1-100000之间的自幂数
一个数字有n位数,每一位的n次方之和等于它本身。
例如153 = 1^3 + 5^3 + 3^3.
1234567891011121314151617181920212223242526 | #include <stdio.h>#include <math.h>int main(){ int i = 0; for (i=0; i <= 100000; i++) { int n = 1; int tmp = i; int sum = 0; while (tmp /= 10) { n++; } tmp = i; while (tmp) { sum = sum + pow(tmp % 10,n); tmp /= 10; } if (i == sum) { printf("%d ",i); } }} |
求一个数字的次方:pow(数字,次方数)
打印菱形
12345678910111213 | * *** ***** ******* ********* ************************ *********** ********* ******* ***** *** * |
123456789101112131415161718192021222324252627282930313233 | #include <stdio.h>int main(){ int line = 0; scanf("%d",&line); int i = 0; for (i = 0; i<line; i++) { int j = 0; for (j = 0; j<line-i-1; j++) { printf(" "); } for (j=0; j<2*i+1; j++) { printf("*"); } printf("\n"); } for (i=0; i<line-1; i++) { int j = 0; for (j = 0; j<=i; j++) { printf(" "); } for (j=0; j<2*(line-1-i)-1; j++) { printf("*"); } printf("\n"); }} |